Merge branch 'master' of https://github.com/github/codeql into pr/erik-krogh/3478

This commit is contained in:
Erik Krogh Kristensen
2020-05-18 07:51:19 +00:00
167 changed files with 7195 additions and 2317 deletions

View File

@@ -4,6 +4,7 @@
* Support for the following frameworks and libraries has been improved:
- [bluebird](http://bluebirdjs.com/)
- [express](https://www.npmjs.com/package/express)
- [fstream](https://www.npmjs.com/package/fstream)
- [jGrowl](https://github.com/stanlemon/jGrowl)
- [jQuery](https://jquery.com/)
@@ -17,6 +18,7 @@
|---------------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Cross-site scripting through DOM (`js/xss-through-dom`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities where existing text from the DOM is used as HTML. Results are not shown on LGTM by default. |
| Incomplete HTML attribute sanitization (`js/incomplete-html-attribute-sanitization`) | security, external/cwe/cwe-20, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities due to incomplete sanitization of HTML meta-characters. Results are shown on LGTM by default. |
| Unsafe expansion of self-closing HTML tag (`js/unsafe-html-expansion`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities caused by unsafe expansion of self-closing HTML tags. |
## Changes to existing queries
@@ -25,10 +27,16 @@
| Misspelled variable name (`js/misspelled-variable-name`) | Message changed | The message for this query now correctly identifies the misspelled variable in additional cases. |
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional file system calls. |
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now recognizes additional command execution calls. |
| Client-side URL redirect (`js/client-side-unvalidated-url-redirection`) | Less results | This query now recognizes additional safe patterns of doing URL redirects. |
| Client-side cross-site scripting (`js/xss`) | Less results | This query now recognizes additional safe strings based on URLs. |
| Incomplete URL scheme check (`js/incomplete-url-scheme-check`) | More results | This query now recognizes additional url scheme checks. |
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | More results | This query now recognizes additional utility functions as vulnerable to prototype polution. |
| Expression has no effect (`js/useless-expression`) | Less results | This query no longer flags an expression when that expression is the only content of the containing file. |
| Unknown directive (`js/unknown-directive`) | Less results | This query no longer flags directives generated by the Babel compiler. |
| Code injection (`js/code-injection`) | More results | More potential vulnerabilities involving NoSQL code operators are now recognized. |
| Zip Slip (`js/zipslip`) | More results | This query now recognizes additional vulnerabilities. |
## Changes to libraries
* A library `semmle.javascript.explore.CallGraph` has been added to help write queries for exploring the call graph.
* Added data flow for `Map` and `Set`, and added matching type-tracking steps that can accessed using the `CollectionsTypeTracking` module.

View File

@@ -184,17 +184,8 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* For example: for a function `int Foo(int p1, int p2)` this would
* return `int p1, int p2`.
*/
string getParameterString() { result = getParameterStringFrom(0) }
private string getParameterStringFrom(int index) {
index = getNumberOfParameters() and
result = ""
or
index = getNumberOfParameters() - 1 and
result = getParameter(index).getTypedName()
or
index < getNumberOfParameters() - 1 and
result = getParameter(index).getTypedName() + ", " + getParameterStringFrom(index + 1)
string getParameterString() {
result = concat(int i | | min(getParameter(i).getTypedName()), ", " order by i)
}
/** Gets a call to this function. */
@@ -616,18 +607,8 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* For example: for a function 'int Foo(int p1, int p2)' this would
* return 'int p1, int p2'.
*/
string getParameterString() { result = getParameterStringFrom(0) }
private string getParameterStringFrom(int index) {
index = getNumberOfParameters() and
result = ""
or
index = getNumberOfParameters() - 1 and
result = getParameterDeclarationEntry(index).getTypedName()
or
index < getNumberOfParameters() - 1 and
result =
getParameterDeclarationEntry(index).getTypedName() + ", " + getParameterStringFrom(index + 1)
string getParameterString() {
result = concat(int i | | min(getParameterDeclarationEntry(i).getTypedName()), ", " order by i)
}
/**

View File

@@ -6,9 +6,13 @@ private import semmle.code.cpp.dataflow.EscapesTree
/**
* A C/C++ access expression. This refers to a function, variable, or enum constant.
*/
abstract class Access extends Expr, NameQualifiableElement {
class Access extends Expr, NameQualifiableElement, @access {
// As `@access` is a union type containing `@routineexpr` (which describes function accesses
// that are called), we need to exclude function calls.
Access() { this instanceof @routineexpr implies not iscall(underlyingElement(this), _) }
/** Gets the accessed function, variable, or enum constant. */
abstract Declaration getTarget();
Declaration getTarget() { none() } // overridden in subclasses
override predicate mayBeImpure() { none() }

View File

@@ -7,7 +7,7 @@ private import semmle.code.cpp.internal.ResolveClass
* Instances of this class are not present in the main AST which is navigated by parent/child links. Instead,
* instances of this class are attached to nodes in the main AST via special conversion links.
*/
abstract class Conversion extends Expr {
class Conversion extends Expr, @conversion {
/** Gets the expression being converted. */
Expr getExpr() { result.getConversion() = this }

View File

@@ -14,12 +14,8 @@ private newtype TOperand =
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
useInstr.getOpcode().hasOperand(tag)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -27,6 +23,57 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/**
* Base class for all register operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class RegisterOperandBase extends TRegisterOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the register operand with the specified parameters.
*/
private RegisterOperandBase registerOperand(
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
) {
result = TRegisterOperand(useInstr, tag, defInstr)
}
/**
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
* will eventually use for this purpose.
*/
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
result = TNonPhiMemoryOperand(useInstr, tag)
}
/**
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class PhiOperandBase extends TPhiOperand {
abstract string toString();
}
/**
* Returns the Phi operand with the specified parameters.
*/
private PhiOperandBase phiOperand(
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
) {
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/
@@ -165,8 +212,8 @@ class Operand extends TOperand {
*/
class MemoryOperand extends Operand {
MemoryOperand() {
this = TNonPhiMemoryOperand(_, _, _, _) or
this = TPhiOperand(_, _, _, _)
this instanceof NonPhiMemoryOperandBase or
this instanceof PhiOperandBase
}
/**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
*/
class NonPhiOperand extends Operand {
Instruction useInstr;
Instruction defInstr;
OperandTag tag;
NonPhiOperand() {
this = TRegisterOperand(useInstr, tag, defInstr) or
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
this = registerOperand(useInstr, tag, _) or
this = nonPhiMemoryOperand(useInstr, tag)
}
final override Instruction getUse() { result = useInstr }
final override Instruction getAnyDef() { result = defInstr }
final override string getDumpLabel() { result = tag.getLabel() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
/**
* An operand that consumes a register (non-memory) result.
*/
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
override RegisterOperandTag tag;
Instruction defInstr;
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() { result = defInstr }
final override Overlap getDefinitionOverlap() {
// All register results overlap exactly with their uses.
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
}
}
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
override MemoryOperandTag tag;
Overlap overlap;
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
final override Overlap getDefinitionOverlap() { result = overlap }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() {
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
}
class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
*/
class AddressOperand extends RegisterOperand {
override AddressOperandTag tag;
override string toString() { result = "Address" }
}
/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/**
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
*/
class LoadOperand extends TypedOperand {
override LoadOperandTag tag;
override string toString() { result = "Load" }
}
/**
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
*/
class StoreValueOperand extends RegisterOperand {
override StoreValueOperandTag tag;
override string toString() { result = "StoreValue" }
}
/**
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
*/
class UnaryOperand extends RegisterOperand {
override UnaryOperandTag tag;
override string toString() { result = "Unary" }
}
/**
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
*/
class LeftOperand extends RegisterOperand {
override LeftOperandTag tag;
override string toString() { result = "Left" }
}
/**
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
*/
class RightOperand extends RegisterOperand {
override RightOperandTag tag;
override string toString() { result = "Right" }
}
/**
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
*/
class ConditionOperand extends RegisterOperand {
override ConditionOperandTag tag;
override string toString() { result = "Condition" }
}
/**
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
*/
class CallTargetOperand extends RegisterOperand {
override CallTargetOperandTag tag;
override string toString() { result = "CallTarget" }
}
/**
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
*/
class ThisArgumentOperand extends ArgumentOperand {
override ThisArgumentOperandTag tag;
override string toString() { result = "ThisArgument" }
}
/**
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
*/
class PositionalArgumentOperand extends ArgumentOperand {
override PositionalArgumentOperandTag tag;
int argIndex;
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
override string toString() { result = "Arg(" + argIndex + ")" }
/**
* Gets the zero-based index of the argument.
*/
final int getIndex() { result = argIndex }
final int getIndex() { result = tag.getArgIndex() }
}
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override string toString() { result = "SideEffect" }
}
/**
* An operand of a `PhiInstruction`.
*/
class PhiInputOperand extends MemoryOperand, TPhiOperand {
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
Overlap overlap;
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
override string toString() { result = "Phi" }
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
class ChiTotalOperand extends NonPhiMemoryOperand {
override ChiTotalOperandTag tag;
override string toString() { result = "ChiTotal" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
}
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
class ChiPartialOperand extends NonPhiMemoryOperand {
override ChiPartialOperandTag tag;
override string toString() { result = "ChiPartial" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
}

View File

@@ -221,7 +221,9 @@ PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
result = TPositionalArgumentOperand(argIndex)
}
class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
abstract class ChiOperandTag extends MemoryOperandTag { }
class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
final override string toString() { result = "ChiTotal" }
final override int getSortOrder() { result = 13 }
@@ -231,7 +233,7 @@ class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
class ChiPartialOperandTag extends MemoryOperandTag, TChiPartialOperand {
class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
final override string toString() { result = "ChiPartial" }
final override int getSortOrder() { result = 14 }

View File

@@ -14,12 +14,8 @@ private newtype TOperand =
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
useInstr.getOpcode().hasOperand(tag)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -27,6 +23,57 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/**
* Base class for all register operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class RegisterOperandBase extends TRegisterOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the register operand with the specified parameters.
*/
private RegisterOperandBase registerOperand(
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
) {
result = TRegisterOperand(useInstr, tag, defInstr)
}
/**
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
* will eventually use for this purpose.
*/
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
result = TNonPhiMemoryOperand(useInstr, tag)
}
/**
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class PhiOperandBase extends TPhiOperand {
abstract string toString();
}
/**
* Returns the Phi operand with the specified parameters.
*/
private PhiOperandBase phiOperand(
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
) {
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/
@@ -165,8 +212,8 @@ class Operand extends TOperand {
*/
class MemoryOperand extends Operand {
MemoryOperand() {
this = TNonPhiMemoryOperand(_, _, _, _) or
this = TPhiOperand(_, _, _, _)
this instanceof NonPhiMemoryOperandBase or
this instanceof PhiOperandBase
}
/**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
*/
class NonPhiOperand extends Operand {
Instruction useInstr;
Instruction defInstr;
OperandTag tag;
NonPhiOperand() {
this = TRegisterOperand(useInstr, tag, defInstr) or
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
this = registerOperand(useInstr, tag, _) or
this = nonPhiMemoryOperand(useInstr, tag)
}
final override Instruction getUse() { result = useInstr }
final override Instruction getAnyDef() { result = defInstr }
final override string getDumpLabel() { result = tag.getLabel() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
/**
* An operand that consumes a register (non-memory) result.
*/
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
override RegisterOperandTag tag;
Instruction defInstr;
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() { result = defInstr }
final override Overlap getDefinitionOverlap() {
// All register results overlap exactly with their uses.
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
}
}
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
override MemoryOperandTag tag;
Overlap overlap;
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
final override Overlap getDefinitionOverlap() { result = overlap }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() {
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
}
class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
*/
class AddressOperand extends RegisterOperand {
override AddressOperandTag tag;
override string toString() { result = "Address" }
}
/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/**
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
*/
class LoadOperand extends TypedOperand {
override LoadOperandTag tag;
override string toString() { result = "Load" }
}
/**
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
*/
class StoreValueOperand extends RegisterOperand {
override StoreValueOperandTag tag;
override string toString() { result = "StoreValue" }
}
/**
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
*/
class UnaryOperand extends RegisterOperand {
override UnaryOperandTag tag;
override string toString() { result = "Unary" }
}
/**
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
*/
class LeftOperand extends RegisterOperand {
override LeftOperandTag tag;
override string toString() { result = "Left" }
}
/**
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
*/
class RightOperand extends RegisterOperand {
override RightOperandTag tag;
override string toString() { result = "Right" }
}
/**
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
*/
class ConditionOperand extends RegisterOperand {
override ConditionOperandTag tag;
override string toString() { result = "Condition" }
}
/**
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
*/
class CallTargetOperand extends RegisterOperand {
override CallTargetOperandTag tag;
override string toString() { result = "CallTarget" }
}
/**
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
*/
class ThisArgumentOperand extends ArgumentOperand {
override ThisArgumentOperandTag tag;
override string toString() { result = "ThisArgument" }
}
/**
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
*/
class PositionalArgumentOperand extends ArgumentOperand {
override PositionalArgumentOperandTag tag;
int argIndex;
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
override string toString() { result = "Arg(" + argIndex + ")" }
/**
* Gets the zero-based index of the argument.
*/
final int getIndex() { result = argIndex }
final int getIndex() { result = tag.getArgIndex() }
}
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override string toString() { result = "SideEffect" }
}
/**
* An operand of a `PhiInstruction`.
*/
class PhiInputOperand extends MemoryOperand, TPhiOperand {
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
Overlap overlap;
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
override string toString() { result = "Phi" }
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
class ChiTotalOperand extends NonPhiMemoryOperand {
override ChiTotalOperandTag tag;
override string toString() { result = "ChiTotal" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
}
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
class ChiPartialOperand extends NonPhiMemoryOperand {
override ChiPartialOperandTag tag;
override string toString() { result = "ChiPartial" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
}

View File

@@ -14,12 +14,8 @@ private newtype TOperand =
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
useInstr.getOpcode().hasOperand(tag)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -27,6 +23,57 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/**
* Base class for all register operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class RegisterOperandBase extends TRegisterOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the register operand with the specified parameters.
*/
private RegisterOperandBase registerOperand(
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
) {
result = TRegisterOperand(useInstr, tag, defInstr)
}
/**
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
* will eventually use for this purpose.
*/
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
result = TNonPhiMemoryOperand(useInstr, tag)
}
/**
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class PhiOperandBase extends TPhiOperand {
abstract string toString();
}
/**
* Returns the Phi operand with the specified parameters.
*/
private PhiOperandBase phiOperand(
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
) {
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/
@@ -165,8 +212,8 @@ class Operand extends TOperand {
*/
class MemoryOperand extends Operand {
MemoryOperand() {
this = TNonPhiMemoryOperand(_, _, _, _) or
this = TPhiOperand(_, _, _, _)
this instanceof NonPhiMemoryOperandBase or
this instanceof PhiOperandBase
}
/**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
*/
class NonPhiOperand extends Operand {
Instruction useInstr;
Instruction defInstr;
OperandTag tag;
NonPhiOperand() {
this = TRegisterOperand(useInstr, tag, defInstr) or
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
this = registerOperand(useInstr, tag, _) or
this = nonPhiMemoryOperand(useInstr, tag)
}
final override Instruction getUse() { result = useInstr }
final override Instruction getAnyDef() { result = defInstr }
final override string getDumpLabel() { result = tag.getLabel() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
/**
* An operand that consumes a register (non-memory) result.
*/
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
override RegisterOperandTag tag;
Instruction defInstr;
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() { result = defInstr }
final override Overlap getDefinitionOverlap() {
// All register results overlap exactly with their uses.
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
}
}
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
override MemoryOperandTag tag;
Overlap overlap;
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
final override Overlap getDefinitionOverlap() { result = overlap }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() {
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
}
class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
*/
class AddressOperand extends RegisterOperand {
override AddressOperandTag tag;
override string toString() { result = "Address" }
}
/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/**
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
*/
class LoadOperand extends TypedOperand {
override LoadOperandTag tag;
override string toString() { result = "Load" }
}
/**
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
*/
class StoreValueOperand extends RegisterOperand {
override StoreValueOperandTag tag;
override string toString() { result = "StoreValue" }
}
/**
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
*/
class UnaryOperand extends RegisterOperand {
override UnaryOperandTag tag;
override string toString() { result = "Unary" }
}
/**
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
*/
class LeftOperand extends RegisterOperand {
override LeftOperandTag tag;
override string toString() { result = "Left" }
}
/**
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
*/
class RightOperand extends RegisterOperand {
override RightOperandTag tag;
override string toString() { result = "Right" }
}
/**
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
*/
class ConditionOperand extends RegisterOperand {
override ConditionOperandTag tag;
override string toString() { result = "Condition" }
}
/**
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
*/
class CallTargetOperand extends RegisterOperand {
override CallTargetOperandTag tag;
override string toString() { result = "CallTarget" }
}
/**
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
*/
class ThisArgumentOperand extends ArgumentOperand {
override ThisArgumentOperandTag tag;
override string toString() { result = "ThisArgument" }
}
/**
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
*/
class PositionalArgumentOperand extends ArgumentOperand {
override PositionalArgumentOperandTag tag;
int argIndex;
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
override string toString() { result = "Arg(" + argIndex + ")" }
/**
* Gets the zero-based index of the argument.
*/
final int getIndex() { result = argIndex }
final int getIndex() { result = tag.getArgIndex() }
}
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override string toString() { result = "SideEffect" }
}
/**
* An operand of a `PhiInstruction`.
*/
class PhiInputOperand extends MemoryOperand, TPhiOperand {
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
Overlap overlap;
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
override string toString() { result = "Phi" }
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
class ChiTotalOperand extends NonPhiMemoryOperand {
override ChiTotalOperandTag tag;
override string toString() { result = "ChiTotal" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
}
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
class ChiPartialOperand extends NonPhiMemoryOperand {
override ChiPartialOperandTag tag;
override string toString() { result = "ChiPartial" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
}

View File

@@ -14,3 +14,4 @@ private import implementations.Strdup
private import implementations.Strftime
private import implementations.StdString
private import implementations.Swap
private import implementations.GetDelim

View File

@@ -0,0 +1,40 @@
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.FlowSource
/**
* The standard functions `getdelim`, `getwdelim` and the glibc variant `__getdelim`.
*/
class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction, RemoteFlowFunction {
GetDelimFunction() { hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) {
i.isParameter(3) and o.isParameterDeref(0)
}
override predicate parameterNeverEscapes(int index) { index = [0, 1, 3] }
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate parameterIsAlwaysReturned(int index) { none() }
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = [0, 1] and
buffer = false and
mustWrite = false
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
i = 3 and buffer = false
}
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(0) and
description = "String read by " + this.getName()
}
}

View File

@@ -1143,6 +1143,13 @@ conversionkinds(
int kind: int ref
);
@conversion = @cast
| @array_to_pointer
| @parexpr
| @reference_to
| @ref_indirect
;
/*
case @funbindexpr.kind of
0 = @normal_call // a normal call
@@ -1800,6 +1807,8 @@ lambda_capture(
@addressable = @function | @variable ;
@accessible = @addressable | @enumconstant ;
@access = @varaccess | @routineexpr ;
fold(
int expr: @foldexpr ref,
string operator: string ref,

View File

@@ -1524,7 +1524,7 @@
</e>
<e>
<k>seconds</k>
<v>12697</v>
<v>12094</v>
</e>
</columnsizes>
<dependencies>
@@ -1570,17 +1570,17 @@
<b>
<a>2</a>
<b>3</b>
<v>21</v>
<v>10</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>2478</v>
<v>2675</v>
</b>
<b>
<a>4</a>
<b>5</b>
<v>7028</v>
<v>6842</v>
</b>
</bs>
</hist>
@@ -1626,8 +1626,8 @@
<budget>12</budget>
<bs>
<b>
<a>1158</a>
<b>1159</b>
<a>1103</a>
<b>1104</b>
<v>10</v>
</b>
</bs>
@@ -1679,18 +1679,18 @@
<v>10</v>
</b>
<b>
<a>14</a>
<b>15</b>
<a>13</a>
<b>14</b>
<v>10</v>
</b>
<b>
<a>565</a>
<b>566</b>
<a>579</a>
<b>580</b>
<v>10</v>
</b>
<b>
<a>693</a>
<b>694</b>
<a>670</a>
<b>671</b>
<v>10</v>
</b>
</bs>
@@ -1707,22 +1707,22 @@
<b>
<a>1</a>
<b>2</b>
<v>8859</v>
<v>7949</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>2313</v>
<v>2401</v>
</b>
<b>
<a>3</a>
<b>5</b>
<v>1107</v>
<b>4</b>
<v>932</v>
</b>
<b>
<a>5</a>
<b>614</b>
<v>416</v>
<a>4</a>
<b>627</b>
<v>811</v>
</b>
</bs>
</hist>
@@ -1738,7 +1738,7 @@
<b>
<a>1</a>
<b>2</b>
<v>12697</v>
<v>12094</v>
</b>
</bs>
</hist>
@@ -1754,17 +1754,17 @@
<b>
<a>1</a>
<b>2</b>
<v>11403</v>
<v>10285</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>1271</v>
<v>1798</v>
</b>
<b>
<a>3</a>
<b>5</b>
<v>21</v>
<b>4</b>
<v>10</v>
</b>
</bs>
</hist>
@@ -2143,7 +2143,7 @@
</e>
<e>
<k>cpu_seconds</k>
<v>7927</v>
<v>8157</v>
</e>
<e>
<k>elapsed_seconds</k>
@@ -2193,17 +2193,17 @@
<b>
<a>1</a>
<b>2</b>
<v>6820</v>
<v>7160</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>778</v>
<v>756</v>
</b>
<b>
<a>3</a>
<b>8</b>
<v>328</v>
<b>6</b>
<v>241</v>
</b>
</bs>
</hist>
@@ -2219,12 +2219,12 @@
<b>
<a>1</a>
<b>2</b>
<v>7587</v>
<v>7675</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>339</v>
<v>482</v>
</b>
</bs>
</hist>
@@ -2240,66 +2240,66 @@
<b>
<a>1</a>
<b>2</b>
<v>10</v>
<v>32</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>21</v>
<v>10</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>21</v>
<v>32</v>
</b>
<b>
<a>4</a>
<b>5</b>
<v>21</v>
</b>
<b>
<a>10</a>
<b>11</b>
<v>21</v>
</b>
<b>
<a>18</a>
<b>19</b>
<a>7</a>
<b>8</b>
<v>10</v>
</b>
<b>
<a>37</a>
<b>38</b>
<a>8</a>
<b>9</b>
<v>10</v>
</b>
<b>
<a>51</a>
<b>52</b>
<a>21</a>
<b>22</b>
<v>10</v>
</b>
<b>
<a>62</a>
<b>63</b>
<a>26</a>
<b>27</b>
<v>10</v>
</b>
<b>
<a>99</a>
<b>100</b>
<a>31</a>
<b>32</b>
<v>10</v>
</b>
<b>
<a>158</a>
<b>159</b>
<a>104</a>
<b>105</b>
<v>10</v>
</b>
<b>
<a>170</a>
<b>171</b>
<a>137</a>
<b>138</b>
<v>10</v>
</b>
<b>
<a>237</a>
<b>238</b>
<a>144</a>
<b>145</b>
<v>10</v>
</b>
<b>
<a>173</a>
<b>174</b>
<v>10</v>
</b>
<b>
<a>206</a>
<b>207</b>
<v>10</v>
</b>
</bs>
@@ -2316,66 +2316,66 @@
<b>
<a>1</a>
<b>2</b>
<v>10</v>
<v>32</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>21</v>
<v>10</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>21</v>
<v>32</v>
</b>
<b>
<a>4</a>
<b>5</b>
<v>21</v>
</b>
<b>
<a>10</a>
<b>11</b>
<v>21</v>
</b>
<b>
<a>18</a>
<b>19</b>
<a>7</a>
<b>8</b>
<v>10</v>
</b>
<b>
<a>35</a>
<b>36</b>
<a>8</a>
<b>9</b>
<v>10</v>
</b>
<b>
<a>50</a>
<b>51</b>
<a>21</a>
<b>22</b>
<v>10</v>
</b>
<b>
<a>59</a>
<b>60</b>
<a>25</a>
<b>26</b>
<v>10</v>
</b>
<b>
<a>74</a>
<b>75</b>
<a>29</a>
<b>30</b>
<v>10</v>
</b>
<b>
<a>144</a>
<b>145</b>
<a>84</a>
<b>85</b>
<v>10</v>
</b>
<b>
<a>162</a>
<b>163</b>
<a>122</a>
<b>123</b>
<v>10</v>
</b>
<b>
<a>173</a>
<b>174</b>
<a>132</a>
<b>133</b>
<v>10</v>
</b>
<b>
<a>150</a>
<b>151</b>
<v>10</v>
</b>
<b>
<a>196</a>
<b>197</b>
<v>10</v>
</b>
</bs>

View File

@@ -96,4 +96,24 @@ void test_outparams() {
char *p2 = nullptr;
flow_to_outparam(&p2, getenv("VAR"));
sink(p2); // tainted
}
}
void *memcpy(void *dst, void *src, int size);
struct ContainsArray {
int arr[16];
int x;
};
void taint_array(ContainsArray *ca, int offset) {
int tainted = getenv("VAR")[0];
memcpy(ca->arr + offset, &tainted, sizeof(int));
}
void test_conflated_fields3(int arbitrary) {
ContainsArray ca;
ca.x = 0;
taint_array(&ca, arbitrary);
sink(ca.x); // not tainted [FALSE POSITIVE]
}

View File

@@ -109,6 +109,17 @@
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... |
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 |
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:10:11:10:13 | p#0 |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:102:31:102:33 | src |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:110:7:110:13 | tainted |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:110:17:110:22 | call to getenv |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:110:17:110:32 | (int)... |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:110:17:110:32 | access to array |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:111:3:111:8 | call to memcpy |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:111:28:111:35 | & ... |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:111:28:111:35 | (void *)... |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:118:11:118:11 | x |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | test_diff.cpp:2:11:2:13 | p#0 |
| globals.cpp:5:20:5:25 | call to getenv | globals.cpp:2:17:2:25 | sinkParam |
| globals.cpp:5:20:5:25 | call to getenv | globals.cpp:5:12:5:16 | local |
| globals.cpp:5:20:5:25 | call to getenv | globals.cpp:5:20:5:25 | call to getenv |

View File

@@ -23,6 +23,12 @@
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... | IR only |
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 | IR only |
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | IR only |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:10:11:10:13 | p#0 | IR only |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:102:20:102:22 | dst | AST only |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:111:10:111:25 | ... + ... | AST only |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:111:29:111:35 | tainted | AST only |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:118:11:118:11 | x | IR only |
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | test_diff.cpp:2:11:2:13 | p#0 | IR only |
| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:13:5:13:11 | global1 | AST only |
| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:5:23:11 | global2 | AST only |
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:11:104:20 | (...) | IR only |

View File

@@ -40,21 +40,21 @@ public:
cc.insert(nullptr);
ct.insert(new C());
sink(&cc); // no flow
sink(&ct); // flow
sink(&ct); // $ast $f-:ir
}
void f1()
{
C *c = new C();
B *b = B::make(c);
sink(b->c); // flow
sink(b->c); // $ast $f-:ir
}
void f2()
{
B *b = new B();
b->set(new C1());
sink(b->get()); // flow
sink((new B(new C()))->get()); // flow
sink(b->get()); // $ast $f-:ir
sink((new B(new C()))->get()); // $ast $f-:ir
}
void f3()
@@ -63,7 +63,7 @@ public:
B *b2;
b2 = setOnB(b1, new C2());
sink(b1->c); // no flow
sink(b2->c); // flow
sink(b2->c); // $ast $f-:ir
}
void f4()
@@ -72,7 +72,7 @@ public:
B *b2;
b2 = setOnBWrap(b1, new C2());
sink(b1->c); // no flow
sink(b2->c); // flow
sink(b2->c); // $ast $f-:ir
}
B *setOnBWrap(B *b1, C *c)
@@ -104,7 +104,7 @@ public:
{
if (C1 *c1 = dynamic_cast<C1 *>(c))
{
sink(c1->a); // flow
sink(c1->a); // $ast $f-:ir
}
C *cc;
if (C2 *c2 = dynamic_cast<C2 *>(c))
@@ -117,7 +117,7 @@ public:
}
if (C1 *c1 = dynamic_cast<C1 *>(cc))
{
sink(c1->a); // no flow, stopped by cast to C2 [FALSE POSITIVE]
sink(c1->a); //$f+:ast
}
}
@@ -129,7 +129,7 @@ public:
{
B *b = new B();
f7(b);
sink(b->c); // flow
sink(b->c); // $ast $f-:ir
}
class D
@@ -149,9 +149,9 @@ public:
{
B *b = new B();
D *d = new D(b, r());
sink(d->b); // flow x2
sink(d->b->c); // flow
sink(b->c); // flow
sink(d->b); // $ast=143:25 $ast=150:12 $f-:ir
sink(d->b->c); // $ast $f-:ir
sink(b->c); // $ast,ir
}
void f10()
@@ -162,11 +162,11 @@ public:
MyList *l3 = new MyList(nullptr, l2);
sink(l3->head); // no flow, b is nested beneath at least one ->next
sink(l3->next->head); // no flow
sink(l3->next->next->head); // flow
sink(l3->next->next->head); // $ast $f-:ir
sink(l3->next->next->next->head); // no flow
for (MyList *l = l3; l != nullptr; l = l->next)
{
sink(l->head); // flow
sink(l->head); // $ast $f-:ir
}
}

View File

@@ -6,7 +6,7 @@ class B
Elem *e = new Elem();
Box1 *b1 = new Box1(e, nullptr);
Box2 *b2 = new Box2(b1);
sink(b2->box1->elem1); // flow
sink(b2->box1->elem1); // $ast $f-:ir
sink(b2->box1->elem2); // no flow
}
@@ -16,7 +16,7 @@ class B
Box1 *b1 = new B::Box1(nullptr, e);
Box2 *b2 = new Box2(b1);
sink(b2->box1->elem1); // no flow
sink(b2->box1->elem2); // flow
sink(b2->box1->elem2); // $ast $f-:ir
}
static void sink(void *o) {}

View File

@@ -26,10 +26,10 @@ public:
void func()
{
sink(s1); // flow
sink(s2); // flow [NOT DETECTED]
sink(s3); // flow
sink(s4); // flow [NOT DETECTED]
sink(s1); // $ast $f-:ir
sink(s2); // $f-:ast $f-:ir
sink(s3); // $ast $f-:ir
sink(s4); // $f-:ast $f-:ir
}
static void sink(const void *o) {}

View File

@@ -19,7 +19,7 @@ public:
};
static void sinkWrap(Box2* b2) {
sink(b2->getBox1()->getElem());
sink(b2->getBox1()->getElem()); // $ast=28:15 $ast=35:15 $ast=42:15 $ast=49:15 $f-:ir
}
Box2* boxfield;
@@ -61,6 +61,6 @@ public:
private:
void f5b() {
sink(boxfield->box->elem);
sink(boxfield->box->elem); // $ast $f-:ir
}
};

View File

@@ -18,7 +18,7 @@ void sink(char *b);
void handlePacket(packet *p)
{
sink(p->data.buffer);
sink(p->data.buffer); // $ast $f-:ir
}
void f(buf* b)
@@ -28,7 +28,7 @@ void f(buf* b)
argument_source(raw);
argument_source(b->buffer);
argument_source(p.data.buffer);
sink(raw);
sink(b->buffer);
sink(raw); // $ast $f-:ir
sink(b->buffer); // $ast $f-:ir
handlePacket(&p);
}

View File

@@ -26,8 +26,8 @@ void callSetters() {
referenceSetter(s2);
copySetter(s3);
sink(s1.m1); // flow
sink(s2.m1); // flow
sink(s1.m1); // $ast,ir
sink(s2.m1); // $ast,ir
sink(s3.m1); // no flow
}
@@ -35,12 +35,12 @@ void assignAfterAlias() {
S s1 = { 0, 0 };
S &ref1 = s1;
ref1.m1 = user_input();
sink(s1.m1); // flow [FALSE NEGATIVE]
sink(s1.m1); // $f-:ast $ir
S s2 = { 0, 0 };
S &ref2 = s2;
s2.m1 = user_input();
sink(ref2.m1); // flow [FALSE NEGATIVE]
sink(ref2.m1); // $f-:ast $ir
}
void assignAfterCopy() {
@@ -59,7 +59,7 @@ void assignBeforeCopy() {
S s2 = { 0, 0 };
s2.m1 = user_input();
S copy2 = s2;
sink(copy2.m1); // flow
sink(copy2.m1); // $ast,ir
}
struct Wrapper {
@@ -77,18 +77,18 @@ void pointerIntermediate() {
Wrapper w = { { 0, 0 } };
S *s = &w.s;
s->m1 = user_input();
sink(w.s.m1); // flow [FALSE NEGATIVE]
sink(w.s.m1); // $f-:ast $ir
}
void referenceIntermediate() {
Wrapper w = { { 0, 0 } };
S &s = w.s;
s.m1 = user_input();
sink(w.s.m1); // flow [FALSE NEGATIVE]
sink(w.s.m1); // $f-:ast $ir
}
void nestedAssign() {
Wrapper w = { { 0, 0 } };
w.s.m1 = user_input();
sink(w.s.m1); // flow
sink(w.s.m1); // $ast,ir
}

View File

@@ -48,25 +48,25 @@ struct S {
void test_setDirectly() {
S s;
s.setDirectly(user_input());
sink(s.getDirectly()); // flow
sink(s.getDirectly()); // $ast $f-:ir
}
void test_setIndirectly() {
S s;
s.setIndirectly(user_input());
sink(s.getIndirectly()); // flow
sink(s.getIndirectly()); // $ast $f-:ir
}
void test_setThroughNonMember() {
S s;
s.setThroughNonMember(user_input());
sink(s.getThroughNonMember()); // flow
sink(s.getThroughNonMember()); // $ast $f-:ir
}
void test_nonMemberSetA() {
S s;
nonMemberSetA(&s, user_input());
sink(nonMemberGetA(&s)); // flow
sink(nonMemberGetA(&s)); // $ast $f-:ir
}
////////////////////
@@ -107,13 +107,13 @@ void test_outer_with_ptr(Outer *pouter) {
taint_inner_a_ptr(pouter->inner_ptr);
taint_a_ptr(&pouter->a);
sink(outer.inner_nested.a); // flow
sink(outer.inner_ptr->a); // flow [NOT DETECTED by IR]
sink(outer.a); // flow [NOT DETECTED]
sink(outer.inner_nested.a); // $ast,ir
sink(outer.inner_ptr->a); // $ast $f-:ir
sink(outer.a); // $f-:ast $f-:ir
sink(pouter->inner_nested.a); // flow
sink(pouter->inner_ptr->a); // flow [NOT DETECTED by IR]
sink(pouter->a); // flow [NOT DETECTED]
sink(pouter->inner_nested.a); // $ast,ir
sink(pouter->inner_ptr->a); // $ast $f-:ir
sink(pouter->a); // $f-:ast $f-:ir
}
void test_outer_with_ref(Outer *pouter) {
@@ -127,11 +127,11 @@ void test_outer_with_ref(Outer *pouter) {
taint_inner_a_ref(*pouter->inner_ptr);
taint_a_ref(pouter->a);
sink(outer.inner_nested.a); // flow
sink(outer.inner_ptr->a); // flow [NOT DETECTED by IR]
sink(outer.a); // flow [NOT DETECTED by IR]
sink(outer.inner_nested.a); // $ast,ir
sink(outer.inner_ptr->a); // $ast $f-:ir
sink(outer.a); // $ast $f-:ir
sink(pouter->inner_nested.a); // flow
sink(pouter->inner_ptr->a); // flow [NOT DETECTED by IR]
sink(pouter->a); // flow [NOT DETECTED by IR]
sink(pouter->inner_nested.a); // $ast,ir
sink(pouter->inner_ptr->a); // $ast $f-:ir
sink(pouter->a); // $ast $f-:ir
}

View File

@@ -22,6 +22,12 @@ public:
Bar() : f(0, 0) {}
};
class Outer
{
public:
Bar inner;
};
int user_input()
{
return 42;
@@ -31,31 +37,32 @@ void sink(int x)
{
}
void bar(Bar &b)
void bar(Outer &b)
{
// The library correctly finds that the four `user_input` sources can make it
// to the `sink` calls, but it also finds some source/sink combinations that
// are impossible. Those false positives here are a consequence of how the
// shared data flow library overapproximates field flow. The library only
// tracks the head (`f`) and the length (2) of the field access path, and
// then it tracks that both `a_` and `b_` have followed `f` in _some_ access
// path somewhere in the search. That makes the library conclude that there
// could be flow to `b.f.a_` even when the flow was actually to `b.f.b_`.
sink(b.f.a()); // flow [FALSE POSITIVE through `b2.f.setB` and `b3.f.setB`]
sink(b.f.b()); // flow [FALSE POSITIVE through `b1.f.setA` and `b3.f.setA`]
// tracks the final two fields (`f` and `inner`) and the length (3) of the field
// access path, and then it tracks that both `a_` and `b_` have followed `f.inner`
// in _some_ access path somewhere in the search. That makes the library conclude
// that there could be flow to `b.inner.f.a_` even when the flow was actually to
// `b.inner.f.b_`.
sink(b.inner.f.a()); // $ast=62:19 $f+:ast=63:19 $ast=64:19 $f+:ast=65:19 $f-:ir
sink(b.inner.f.b()); // $f+:ast=62:19 $ast=63:19 $f+:ast=64:19 $ast=65:19 $f-:ir
}
void foo()
{
Bar b1;
Bar b2;
Bar b3;
Bar b4;
Outer b1;
Outer b2;
Outer b3;
Outer b4;
b1.f.setA(user_input());
b2.f.setB(user_input());
b3.f.setA(user_input());
b3.f.setB(user_input());
b1.inner.f.setA(user_input());
b2.inner.f.setB(user_input());
b3.inner.f.setA(user_input());
b3.inner.f.setB(user_input());
// Only a() should alert
bar(b1);

View File

@@ -25,8 +25,8 @@ public:
void bar(Foo &f)
{
sink(f.a()); // flow (through `f` and `h`)
sink(f.b()); // flow (through `g` and `h`)
sink(f.a()); //$ast=34:11 $ast=36:11 $f-:ir
sink(f.b()); //$ast=35:14 $ast=36:25 $f-:ir
}
void foo()

View File

@@ -4,9 +4,13 @@ uniqueEnclosingCallable
uniqueTypeBound
| complex.cpp:22:11:22:17 | constructor init of field f [post-this] | Node should have one type bound but has 0. |
| complex.cpp:22:11:22:17 | constructor init of field f [pre-this] | Node should have one type bound but has 0. |
| complex.cpp:25:7:25:7 | constructor init of field inner [post-this] | Node should have one type bound but has 0. |
| complex.cpp:25:7:25:7 | constructor init of field inner [pre-this] | Node should have one type bound but has 0. |
uniqueTypeRepr
| complex.cpp:22:11:22:17 | constructor init of field f [post-this] | Node should have one type representation but has 0. |
| complex.cpp:22:11:22:17 | constructor init of field f [pre-this] | Node should have one type representation but has 0. |
| complex.cpp:25:7:25:7 | constructor init of field inner [post-this] | Node should have one type representation but has 0. |
| complex.cpp:25:7:25:7 | constructor init of field inner [pre-this] | Node should have one type representation but has 0. |
uniqueNodeLocation
| A.cpp:38:7:38:8 | call to C | Node should have one location but has 2. |
| A.cpp:39:7:39:8 | call to C | Node should have one location but has 2. |

View File

@@ -1,825 +0,0 @@
edges
| A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... |
| A.cpp:47:12:47:18 | new | A.cpp:48:20:48:20 | c |
| A.cpp:48:12:48:18 | call to make [c] | A.cpp:49:10:49:10 | b [c] |
| A.cpp:48:20:48:20 | c | A.cpp:48:12:48:18 | call to make [c] |
| A.cpp:49:10:49:10 | b [c] | A.cpp:49:13:49:13 | c |
| A.cpp:55:5:55:5 | ref arg b [c] | A.cpp:56:10:56:10 | b [c] |
| A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | ref arg b [c] |
| A.cpp:56:10:56:10 | b [c] | A.cpp:56:13:56:15 | call to get |
| A.cpp:57:11:57:24 | call to B [c] | A.cpp:57:11:57:24 | new [c] |
| A.cpp:57:11:57:24 | new [c] | A.cpp:57:28:57:30 | call to get |
| A.cpp:57:17:57:23 | new | A.cpp:57:11:57:24 | call to B [c] |
| A.cpp:64:10:64:15 | call to setOnB [c] | A.cpp:66:10:66:11 | b2 [c] |
| A.cpp:64:21:64:28 | new | A.cpp:64:10:64:15 | call to setOnB [c] |
| A.cpp:66:10:66:11 | b2 [c] | A.cpp:66:14:66:14 | c |
| A.cpp:73:10:73:19 | call to setOnBWrap [c] | A.cpp:75:10:75:11 | b2 [c] |
| A.cpp:73:25:73:32 | new | A.cpp:73:10:73:19 | call to setOnBWrap [c] |
| A.cpp:75:10:75:11 | b2 [c] | A.cpp:75:14:75:14 | c |
| A.cpp:98:12:98:18 | new | A.cpp:100:5:100:13 | ... = ... |
| A.cpp:100:5:100:6 | c1 [post update] [a] | A.cpp:101:8:101:9 | c1 [a] |
| A.cpp:100:5:100:13 | ... = ... | A.cpp:100:5:100:6 | c1 [post update] [a] |
| A.cpp:101:8:101:9 | c1 [a] | A.cpp:103:14:103:14 | c [a] |
| A.cpp:103:14:103:14 | c [a] | A.cpp:107:12:107:13 | c1 [a] |
| A.cpp:103:14:103:14 | c [a] | A.cpp:120:12:120:13 | c1 [a] |
| A.cpp:107:12:107:13 | c1 [a] | A.cpp:107:16:107:16 | a |
| A.cpp:120:12:120:13 | c1 [a] | A.cpp:120:16:120:16 | a |
| A.cpp:126:5:126:5 | ref arg b [c] | A.cpp:131:8:131:8 | ref arg b [c] |
| A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | ref arg b [c] |
| A.cpp:131:8:131:8 | ref arg b [c] | A.cpp:132:10:132:10 | b [c] |
| A.cpp:132:10:132:10 | b [c] | A.cpp:132:13:132:13 | c |
| A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:143:7:143:31 | ... = ... [c] |
| A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:151:18:151:18 | ref arg b [c] |
| A.cpp:142:7:142:20 | ... = ... | A.cpp:142:7:142:7 | b [post update] [c] |
| A.cpp:142:14:142:20 | new | A.cpp:142:7:142:20 | ... = ... |
| A.cpp:143:7:143:10 | this [post update] [b, c] | A.cpp:151:12:151:24 | call to D [b, c] |
| A.cpp:143:7:143:10 | this [post update] [b] | A.cpp:151:12:151:24 | call to D [b] |
| A.cpp:143:7:143:31 | ... = ... | A.cpp:143:7:143:10 | this [post update] [b] |
| A.cpp:143:7:143:31 | ... = ... [c] | A.cpp:143:7:143:10 | this [post update] [b, c] |
| A.cpp:143:25:143:31 | new | A.cpp:143:7:143:31 | ... = ... |
| A.cpp:150:12:150:18 | new | A.cpp:151:18:151:18 | b |
| A.cpp:151:12:151:24 | call to D [b, c] | A.cpp:153:10:153:10 | d [b, c] |
| A.cpp:151:12:151:24 | call to D [b] | A.cpp:152:10:152:10 | d [b] |
| A.cpp:151:18:151:18 | b | A.cpp:151:12:151:24 | call to D [b] |
| A.cpp:151:18:151:18 | ref arg b [c] | A.cpp:154:10:154:10 | b [c] |
| A.cpp:152:10:152:10 | d [b] | A.cpp:152:13:152:13 | b |
| A.cpp:153:10:153:10 | d [b, c] | A.cpp:153:13:153:13 | b [c] |
| A.cpp:153:13:153:13 | b [c] | A.cpp:153:16:153:16 | c |
| A.cpp:154:10:154:10 | b [c] | A.cpp:154:13:154:13 | c |
| A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b |
| A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | l1 [head] |
| A.cpp:160:29:160:29 | b | A.cpp:160:18:160:60 | call to MyList [head] |
| A.cpp:161:18:161:40 | call to MyList [next, head] | A.cpp:162:38:162:39 | l2 [next, head] |
| A.cpp:161:38:161:39 | l1 [head] | A.cpp:161:18:161:40 | call to MyList [next, head] |
| A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] | A.cpp:165:10:165:11 | l3 [next, next, ... (3)] |
| A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] | A.cpp:167:44:167:44 | l [next, next, ... (3)] |
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] |
| A.cpp:165:10:165:11 | l3 [next, next, ... (3)] | A.cpp:165:14:165:17 | next [next, head] |
| A.cpp:165:14:165:17 | next [next, head] | A.cpp:165:20:165:23 | next [head] |
| A.cpp:165:20:165:23 | next [head] | A.cpp:165:26:165:29 | head |
| A.cpp:167:44:167:44 | l [next, head] | A.cpp:167:47:167:50 | next [head] |
| A.cpp:167:44:167:44 | l [next, next, ... (3)] | A.cpp:167:47:167:50 | next [next, head] |
| A.cpp:167:47:167:50 | next [head] | A.cpp:169:12:169:12 | l [head] |
| A.cpp:167:47:167:50 | next [next, head] | A.cpp:167:44:167:44 | l [next, head] |
| A.cpp:169:12:169:12 | l [head] | A.cpp:169:15:169:18 | head |
| B.cpp:6:15:6:24 | new | B.cpp:7:25:7:25 | e |
| B.cpp:7:16:7:35 | call to Box1 [elem1] | B.cpp:8:25:8:26 | b1 [elem1] |
| B.cpp:7:25:7:25 | e | B.cpp:7:16:7:35 | call to Box1 [elem1] |
| B.cpp:8:16:8:27 | call to Box2 [box1, elem1] | B.cpp:9:10:9:11 | b2 [box1, elem1] |
| B.cpp:8:25:8:26 | b1 [elem1] | B.cpp:8:16:8:27 | call to Box2 [box1, elem1] |
| B.cpp:9:10:9:11 | b2 [box1, elem1] | B.cpp:9:14:9:17 | box1 [elem1] |
| B.cpp:9:14:9:17 | box1 [elem1] | B.cpp:9:20:9:24 | elem1 |
| B.cpp:15:15:15:27 | new | B.cpp:16:37:16:37 | e |
| B.cpp:16:16:16:38 | call to Box1 [elem2] | B.cpp:17:25:17:26 | b1 [elem2] |
| B.cpp:16:37:16:37 | e | B.cpp:16:16:16:38 | call to Box1 [elem2] |
| B.cpp:17:16:17:27 | call to Box2 [box1, elem2] | B.cpp:19:10:19:11 | b2 [box1, elem2] |
| B.cpp:17:25:17:26 | b1 [elem2] | B.cpp:17:16:17:27 | call to Box2 [box1, elem2] |
| B.cpp:19:10:19:11 | b2 [box1, elem2] | B.cpp:19:14:19:17 | box1 [elem2] |
| B.cpp:19:14:19:17 | box1 [elem2] | B.cpp:19:20:19:24 | elem2 |
| C.cpp:18:12:18:18 | call to C [s1] | C.cpp:19:5:19:5 | c [s1] |
| C.cpp:18:12:18:18 | call to C [s3] | C.cpp:19:5:19:5 | c [s3] |
| C.cpp:19:5:19:5 | c [s1] | C.cpp:27:8:27:11 | this [s1] |
| C.cpp:19:5:19:5 | c [s3] | C.cpp:27:8:27:11 | this [s3] |
| C.cpp:22:9:22:22 | constructor init of field s1 [post-this] [s1] | C.cpp:18:12:18:18 | call to C [s1] |
| C.cpp:22:12:22:21 | new | C.cpp:22:9:22:22 | constructor init of field s1 [post-this] [s1] |
| C.cpp:24:5:24:8 | this [post update] [s3] | C.cpp:18:12:18:18 | call to C [s3] |
| C.cpp:24:5:24:25 | ... = ... | C.cpp:24:5:24:8 | this [post update] [s3] |
| C.cpp:24:16:24:25 | new | C.cpp:24:5:24:25 | ... = ... |
| C.cpp:27:8:27:11 | this [s1] | C.cpp:29:10:29:11 | this [s1] |
| C.cpp:27:8:27:11 | this [s3] | C.cpp:31:10:31:11 | this [s3] |
| C.cpp:29:10:29:11 | this [s1] | C.cpp:29:10:29:11 | s1 |
| C.cpp:31:10:31:11 | this [s3] | C.cpp:31:10:31:11 | s3 |
| D.cpp:21:30:21:31 | b2 [box, elem] | D.cpp:22:10:22:11 | b2 [box, elem] |
| D.cpp:22:10:22:11 | b2 [box, elem] | D.cpp:22:14:22:20 | call to getBox1 [elem] |
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:22:25:22:31 | call to getElem |
| D.cpp:28:15:28:24 | new | D.cpp:30:5:30:20 | ... = ... |
| D.cpp:30:5:30:5 | b [post update] [box, elem] | D.cpp:31:14:31:14 | b [box, elem] |
| D.cpp:30:5:30:20 | ... = ... | D.cpp:30:8:30:10 | box [post update] [elem] |
| D.cpp:30:8:30:10 | box [post update] [elem] | D.cpp:30:5:30:5 | b [post update] [box, elem] |
| D.cpp:31:14:31:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
| D.cpp:35:15:35:24 | new | D.cpp:37:21:37:21 | e |
| D.cpp:37:5:37:5 | b [post update] [box, elem] | D.cpp:38:14:38:14 | b [box, elem] |
| D.cpp:37:8:37:10 | ref arg box [elem] | D.cpp:37:5:37:5 | b [post update] [box, elem] |
| D.cpp:37:21:37:21 | e | D.cpp:37:8:37:10 | ref arg box [elem] |
| D.cpp:38:14:38:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
| D.cpp:42:15:42:24 | new | D.cpp:44:5:44:26 | ... = ... |
| D.cpp:44:5:44:5 | ref arg b [box, elem] | D.cpp:45:14:45:14 | b [box, elem] |
| D.cpp:44:5:44:26 | ... = ... | D.cpp:44:8:44:14 | call to getBox1 [post update] [elem] |
| D.cpp:44:8:44:14 | call to getBox1 [post update] [elem] | D.cpp:44:5:44:5 | ref arg b [box, elem] |
| D.cpp:45:14:45:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
| D.cpp:49:15:49:24 | new | D.cpp:51:27:51:27 | e |
| D.cpp:51:5:51:5 | ref arg b [box, elem] | D.cpp:52:14:52:14 | b [box, elem] |
| D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] | D.cpp:51:5:51:5 | ref arg b [box, elem] |
| D.cpp:51:27:51:27 | e | D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] |
| D.cpp:52:14:52:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
| D.cpp:56:15:56:24 | new | D.cpp:58:5:58:27 | ... = ... |
| D.cpp:58:5:58:12 | boxfield [post update] [box, elem] | D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] |
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] | D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] |
| D.cpp:58:5:58:27 | ... = ... | D.cpp:58:15:58:17 | box [post update] [elem] |
| D.cpp:58:15:58:17 | box [post update] [elem] | D.cpp:58:5:58:12 | boxfield [post update] [box, elem] |
| D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] | D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] |
| D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] | D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] |
| D.cpp:64:10:64:17 | boxfield [box, elem] | D.cpp:64:20:64:22 | box [elem] |
| D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] | D.cpp:64:10:64:17 | boxfield [box, elem] |
| D.cpp:64:20:64:22 | box [elem] | D.cpp:64:25:64:28 | elem |
| E.cpp:19:27:19:27 | p [data, buffer] | E.cpp:21:10:21:10 | p [data, buffer] |
| E.cpp:21:10:21:10 | p [data, buffer] | E.cpp:21:13:21:16 | data [buffer] |
| E.cpp:21:13:21:16 | data [buffer] | E.cpp:21:18:21:23 | buffer |
| E.cpp:28:21:28:23 | ref arg raw | E.cpp:31:10:31:12 | raw |
| E.cpp:29:21:29:21 | b [post update] [buffer] | E.cpp:32:10:32:10 | b [buffer] |
| E.cpp:29:24:29:29 | ref arg buffer | E.cpp:29:21:29:21 | b [post update] [buffer] |
| E.cpp:30:21:30:21 | p [post update] [data, buffer] | E.cpp:33:18:33:19 | & ... [data, buffer] |
| E.cpp:30:23:30:26 | data [post update] [buffer] | E.cpp:30:21:30:21 | p [post update] [data, buffer] |
| E.cpp:30:28:30:33 | ref arg buffer | E.cpp:30:23:30:26 | data [post update] [buffer] |
| E.cpp:32:10:32:10 | b [buffer] | E.cpp:32:13:32:18 | buffer |
| E.cpp:33:18:33:19 | & ... [data, buffer] | E.cpp:19:27:19:27 | p [data, buffer] |
| aliasing.cpp:9:3:9:3 | s [post update] [m1] | aliasing.cpp:25:17:25:19 | ref arg & ... [m1] |
| aliasing.cpp:9:3:9:22 | ... = ... | aliasing.cpp:9:3:9:3 | s [post update] [m1] |
| aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:9:3:9:22 | ... = ... |
| aliasing.cpp:12:25:12:25 | s [m1] | aliasing.cpp:26:19:26:20 | ref arg s2 [m1] |
| aliasing.cpp:13:3:13:3 | s [post update] [m1] | aliasing.cpp:12:25:12:25 | s [m1] |
| aliasing.cpp:13:3:13:3 | s [post update] [m1] | aliasing.cpp:26:19:26:20 | ref arg s2 [m1] |
| aliasing.cpp:13:3:13:21 | ... = ... | aliasing.cpp:13:3:13:3 | s [post update] [m1] |
| aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:13:3:13:21 | ... = ... |
| aliasing.cpp:25:17:25:19 | ref arg & ... [m1] | aliasing.cpp:29:8:29:9 | s1 [m1] |
| aliasing.cpp:26:19:26:20 | ref arg s2 [m1] | aliasing.cpp:30:8:30:9 | s2 [m1] |
| aliasing.cpp:29:8:29:9 | s1 [m1] | aliasing.cpp:29:11:29:12 | m1 |
| aliasing.cpp:30:8:30:9 | s2 [m1] | aliasing.cpp:30:11:30:12 | m1 |
| aliasing.cpp:60:3:60:4 | s2 [post update] [m1] | aliasing.cpp:62:8:62:12 | copy2 [m1] |
| aliasing.cpp:60:3:60:22 | ... = ... | aliasing.cpp:60:3:60:4 | s2 [post update] [m1] |
| aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:60:3:60:22 | ... = ... |
| aliasing.cpp:62:8:62:12 | copy2 [m1] | aliasing.cpp:62:14:62:15 | m1 |
| aliasing.cpp:92:3:92:3 | w [post update] [s, m1] | aliasing.cpp:93:8:93:8 | w [s, m1] |
| aliasing.cpp:92:3:92:23 | ... = ... | aliasing.cpp:92:5:92:5 | s [post update] [m1] |
| aliasing.cpp:92:5:92:5 | s [post update] [m1] | aliasing.cpp:92:3:92:3 | w [post update] [s, m1] |
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:92:3:92:23 | ... = ... |
| aliasing.cpp:93:8:93:8 | w [s, m1] | aliasing.cpp:93:10:93:10 | s [m1] |
| aliasing.cpp:93:10:93:10 | s [m1] | aliasing.cpp:93:12:93:13 | m1 |
| by_reference.cpp:50:3:50:3 | ref arg s [a] | by_reference.cpp:51:8:51:8 | s [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | ref arg s [a] |
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
| by_reference.cpp:56:3:56:3 | ref arg s [a] | by_reference.cpp:57:8:57:8 | s [a] |
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:3:56:3 | ref arg s [a] |
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly |
| by_reference.cpp:62:3:62:3 | ref arg s [a] | by_reference.cpp:63:8:63:8 | s [a] |
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:62:3:62:3 | ref arg s [a] |
| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
| by_reference.cpp:68:17:68:18 | ref arg & ... [a] | by_reference.cpp:69:22:69:23 | & ... [a] |
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | ref arg & ... [a] |
| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:102:21:102:39 | ref arg & ... [a] |
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] |
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:106:21:106:41 | ref arg & ... [a] |
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:107:29:107:37 | ref arg inner_ptr [a] |
| by_reference.cpp:84:3:84:25 | ... = ... | by_reference.cpp:84:3:84:7 | inner [post update] [a] |
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:84:3:84:25 | ... = ... |
| by_reference.cpp:87:31:87:35 | inner [a] | by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] |
| by_reference.cpp:87:31:87:35 | inner [a] | by_reference.cpp:123:21:123:36 | ref arg * ... [a] |
| by_reference.cpp:87:31:87:35 | inner [a] | by_reference.cpp:126:29:126:40 | ref arg inner_nested [a] |
| by_reference.cpp:87:31:87:35 | inner [a] | by_reference.cpp:127:21:127:38 | ref arg * ... [a] |
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:87:31:87:35 | inner [a] |
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] |
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:123:21:123:36 | ref arg * ... [a] |
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:126:29:126:40 | ref arg inner_nested [a] |
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:127:21:127:38 | ref arg * ... [a] |
| by_reference.cpp:88:3:88:24 | ... = ... | by_reference.cpp:88:3:88:7 | inner [post update] [a] |
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:3:88:24 | ... = ... |
| by_reference.cpp:95:25:95:26 | pa | by_reference.cpp:124:21:124:21 | ref arg a |
| by_reference.cpp:95:25:95:26 | pa | by_reference.cpp:128:23:128:23 | ref arg a |
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:95:25:95:26 | pa |
| by_reference.cpp:102:21:102:39 | ref arg & ... [a] | by_reference.cpp:102:28:102:39 | inner_nested [inner post update] [a] |
| by_reference.cpp:102:22:102:26 | outer [post update] [inner_nested, a] | by_reference.cpp:110:8:110:12 | outer [inner_nested, a] |
| by_reference.cpp:102:28:102:39 | inner_nested [inner post update] [a] | by_reference.cpp:102:22:102:26 | outer [post update] [inner_nested, a] |
| by_reference.cpp:103:21:103:25 | outer [post update] [inner_ptr, a] | by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] |
| by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] | by_reference.cpp:103:21:103:25 | outer [post update] [inner_ptr, a] |
| by_reference.cpp:106:21:106:41 | ref arg & ... [a] | by_reference.cpp:106:30:106:41 | inner_nested [inner post update] [a] |
| by_reference.cpp:106:22:106:27 | pouter [post update] [inner_nested, a] | by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] |
| by_reference.cpp:106:30:106:41 | inner_nested [inner post update] [a] | by_reference.cpp:106:22:106:27 | pouter [post update] [inner_nested, a] |
| by_reference.cpp:107:21:107:26 | pouter [post update] [inner_ptr, a] | by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] |
| by_reference.cpp:107:29:107:37 | ref arg inner_ptr [a] | by_reference.cpp:107:21:107:26 | pouter [post update] [inner_ptr, a] |
| by_reference.cpp:110:8:110:12 | outer [inner_nested, a] | by_reference.cpp:110:14:110:25 | inner_nested [a] |
| by_reference.cpp:110:14:110:25 | inner_nested [a] | by_reference.cpp:110:27:110:27 | a |
| by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] | by_reference.cpp:111:14:111:22 | inner_ptr [a] |
| by_reference.cpp:111:14:111:22 | inner_ptr [a] | by_reference.cpp:111:25:111:25 | a |
| by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] | by_reference.cpp:114:16:114:27 | inner_nested [a] |
| by_reference.cpp:114:16:114:27 | inner_nested [a] | by_reference.cpp:114:29:114:29 | a |
| by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] | by_reference.cpp:115:16:115:24 | inner_ptr [a] |
| by_reference.cpp:115:16:115:24 | inner_ptr [a] | by_reference.cpp:115:27:115:27 | a |
| by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] | by_reference.cpp:130:8:130:12 | outer [inner_nested, a] |
| by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] | by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] |
| by_reference.cpp:123:21:123:36 | ref arg * ... [a] | by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] [a] |
| by_reference.cpp:123:22:123:26 | outer [post update] [inner_ptr, a] | by_reference.cpp:131:8:131:12 | outer [inner_ptr, a] |
| by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] [a] | by_reference.cpp:123:22:123:26 | outer [post update] [inner_ptr, a] |
| by_reference.cpp:124:15:124:19 | outer [post update] [a] | by_reference.cpp:132:8:132:12 | outer [a] |
| by_reference.cpp:124:21:124:21 | ref arg a | by_reference.cpp:124:15:124:19 | outer [post update] [a] |
| by_reference.cpp:126:21:126:26 | pouter [post update] [inner_nested, a] | by_reference.cpp:134:8:134:13 | pouter [inner_nested, a] |
| by_reference.cpp:126:29:126:40 | ref arg inner_nested [a] | by_reference.cpp:126:21:126:26 | pouter [post update] [inner_nested, a] |
| by_reference.cpp:127:21:127:38 | ref arg * ... [a] | by_reference.cpp:127:30:127:38 | inner_ptr [inner post update] [a] |
| by_reference.cpp:127:22:127:27 | pouter [post update] [inner_ptr, a] | by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] |
| by_reference.cpp:127:30:127:38 | inner_ptr [inner post update] [a] | by_reference.cpp:127:22:127:27 | pouter [post update] [inner_ptr, a] |
| by_reference.cpp:128:15:128:20 | pouter [post update] [a] | by_reference.cpp:136:8:136:13 | pouter [a] |
| by_reference.cpp:128:23:128:23 | ref arg a | by_reference.cpp:128:15:128:20 | pouter [post update] [a] |
| by_reference.cpp:130:8:130:12 | outer [inner_nested, a] | by_reference.cpp:130:14:130:25 | inner_nested [a] |
| by_reference.cpp:130:14:130:25 | inner_nested [a] | by_reference.cpp:130:27:130:27 | a |
| by_reference.cpp:131:8:131:12 | outer [inner_ptr, a] | by_reference.cpp:131:14:131:22 | inner_ptr [a] |
| by_reference.cpp:131:14:131:22 | inner_ptr [a] | by_reference.cpp:131:25:131:25 | a |
| by_reference.cpp:132:8:132:12 | outer [a] | by_reference.cpp:132:14:132:14 | a |
| by_reference.cpp:134:8:134:13 | pouter [inner_nested, a] | by_reference.cpp:134:16:134:27 | inner_nested [a] |
| by_reference.cpp:134:16:134:27 | inner_nested [a] | by_reference.cpp:134:29:134:29 | a |
| by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | by_reference.cpp:135:16:135:24 | inner_ptr [a] |
| by_reference.cpp:135:16:135:24 | inner_ptr [a] | by_reference.cpp:135:27:135:27 | a |
| by_reference.cpp:136:8:136:13 | pouter [a] | by_reference.cpp:136:16:136:16 | a |
| complex.cpp:34:15:34:15 | b [f, a_] | complex.cpp:44:8:44:8 | b [f, a_] |
| complex.cpp:34:15:34:15 | b [f, b_] | complex.cpp:45:8:45:8 | b [f, b_] |
| complex.cpp:44:8:44:8 | b [f, a_] | complex.cpp:44:10:44:10 | f [a_] |
| complex.cpp:44:10:44:10 | f [a_] | complex.cpp:44:12:44:12 | call to a |
| complex.cpp:45:8:45:8 | b [f, b_] | complex.cpp:45:10:45:10 | f [b_] |
| complex.cpp:45:10:45:10 | f [b_] | complex.cpp:45:12:45:12 | call to b |
| complex.cpp:55:3:55:4 | b1 [post update] [f, a_] | complex.cpp:61:7:61:8 | b1 [f, a_] |
| complex.cpp:55:6:55:6 | ref arg f [a_] | complex.cpp:55:3:55:4 | b1 [post update] [f, a_] |
| complex.cpp:55:13:55:22 | call to user_input | complex.cpp:55:6:55:6 | ref arg f [a_] |
| complex.cpp:56:3:56:4 | b2 [post update] [f, b_] | complex.cpp:64:7:64:8 | b2 [f, b_] |
| complex.cpp:56:6:56:6 | ref arg f [b_] | complex.cpp:56:3:56:4 | b2 [post update] [f, b_] |
| complex.cpp:56:13:56:22 | call to user_input | complex.cpp:56:6:56:6 | ref arg f [b_] |
| complex.cpp:57:3:57:4 | b3 [post update] [f, a_] | complex.cpp:67:7:67:8 | b3 [f, a_] |
| complex.cpp:57:6:57:6 | ref arg f [a_] | complex.cpp:57:3:57:4 | b3 [post update] [f, a_] |
| complex.cpp:57:13:57:22 | call to user_input | complex.cpp:57:6:57:6 | ref arg f [a_] |
| complex.cpp:58:3:58:4 | b3 [post update] [f, b_] | complex.cpp:67:7:67:8 | b3 [f, b_] |
| complex.cpp:58:6:58:6 | ref arg f [b_] | complex.cpp:58:3:58:4 | b3 [post update] [f, b_] |
| complex.cpp:58:13:58:22 | call to user_input | complex.cpp:58:6:58:6 | ref arg f [b_] |
| complex.cpp:61:7:61:8 | b1 [f, a_] | complex.cpp:34:15:34:15 | b [f, a_] |
| complex.cpp:64:7:64:8 | b2 [f, b_] | complex.cpp:34:15:34:15 | b [f, b_] |
| complex.cpp:67:7:67:8 | b3 [f, a_] | complex.cpp:34:15:34:15 | b [f, a_] |
| complex.cpp:67:7:67:8 | b3 [f, b_] | complex.cpp:34:15:34:15 | b [f, b_] |
| constructors.cpp:26:15:26:15 | f [a_] | constructors.cpp:28:10:28:10 | f [a_] |
| constructors.cpp:26:15:26:15 | f [b_] | constructors.cpp:29:10:29:10 | f [b_] |
| constructors.cpp:28:10:28:10 | f [a_] | constructors.cpp:28:12:28:12 | call to a |
| constructors.cpp:29:10:29:10 | f [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 | call to Foo [a_] |
| constructors.cpp:34:11:34:26 | call to Foo [a_] | constructors.cpp:40:9:40:9 | f [a_] |
| constructors.cpp:35:11:35:26 | call to Foo [b_] | constructors.cpp:43:9:43:9 | g [b_] |
| constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:35:11:35:26 | call to Foo [b_] |
| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:36:11:36:37 | call to Foo [a_] |
| constructors.cpp:36:11:36:37 | call to Foo [a_] | constructors.cpp:46:9:46:9 | h [a_] |
| constructors.cpp:36:11:36:37 | call to Foo [b_] | constructors.cpp:46:9:46:9 | h [b_] |
| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:36:11:36:37 | call to Foo [b_] |
| constructors.cpp:40:9:40:9 | f [a_] | constructors.cpp:26:15:26:15 | f [a_] |
| constructors.cpp:43:9:43:9 | g [b_] | constructors.cpp:26:15:26:15 | f [b_] |
| constructors.cpp:46:9:46:9 | h [a_] | constructors.cpp:26:15:26:15 | f [a_] |
| constructors.cpp:46:9:46:9 | h [b_] | constructors.cpp:26:15:26:15 | f [b_] |
| qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] | qualifiers.cpp:23:10:23:14 | outer [inner, a] |
| qualifiers.cpp:22:5:22:38 | ... = ... | qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] |
| qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] | qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] |
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:22:5:22:38 | ... = ... |
| qualifiers.cpp:23:10:23:14 | outer [inner, a] | qualifiers.cpp:23:16:23:20 | inner [a] |
| qualifiers.cpp:23:16:23:20 | inner [a] | qualifiers.cpp:23:23:23:23 | a |
| qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] | qualifiers.cpp:28:10:28:14 | outer [inner, a] |
| qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] | qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] |
| qualifiers.cpp:28:10:28:14 | outer [inner, a] | qualifiers.cpp:28:16:28:20 | inner [a] |
| qualifiers.cpp:28:16:28:20 | inner [a] | qualifiers.cpp:28:23:28:23 | a |
| qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] | qualifiers.cpp:33:10:33:14 | outer [inner, a] |
| qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] | qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] |
| qualifiers.cpp:33:10:33:14 | outer [inner, a] | qualifiers.cpp:33:16:33:20 | inner [a] |
| qualifiers.cpp:33:16:33:20 | inner [a] | qualifiers.cpp:33:23:33:23 | a |
| qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] |
| qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] | qualifiers.cpp:38:10:38:14 | outer [inner, a] |
| qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] | qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] |
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] |
| qualifiers.cpp:38:10:38:14 | outer [inner, a] | qualifiers.cpp:38:16:38:20 | inner [a] |
| qualifiers.cpp:38:16:38:20 | inner [a] | qualifiers.cpp:38:23:38:23 | a |
| qualifiers.cpp:42:5:42:40 | ... = ... | qualifiers.cpp:42:6:42:22 | * ... [post update] [a] |
| qualifiers.cpp:42:6:42:22 | * ... [post update] [a] | qualifiers.cpp:42:13:42:20 | call to getInner [inner post update] [a] |
| qualifiers.cpp:42:7:42:11 | ref arg outer [inner, a] | qualifiers.cpp:43:10:43:14 | outer [inner, a] |
| qualifiers.cpp:42:13:42:20 | call to getInner [inner post update] [a] | qualifiers.cpp:42:7:42:11 | ref arg outer [inner, a] |
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:42:5:42:40 | ... = ... |
| qualifiers.cpp:43:10:43:14 | outer [inner, a] | qualifiers.cpp:43:16:43:20 | inner [a] |
| qualifiers.cpp:43:16:43:20 | inner [a] | qualifiers.cpp:43:23:43:23 | a |
| qualifiers.cpp:47:5:47:42 | ... = ... | qualifiers.cpp:47:15:47:22 | call to getInner [post update] [a] |
| qualifiers.cpp:47:6:47:11 | ref arg & ... [inner, a] | qualifiers.cpp:48:10:48:14 | outer [inner, a] |
| qualifiers.cpp:47:15:47:22 | call to getInner [post update] [a] | qualifiers.cpp:47:6:47:11 | ref arg & ... [inner, a] |
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | qualifiers.cpp:48:16:48:20 | inner [a] |
| qualifiers.cpp:48:16:48:20 | inner [a] | qualifiers.cpp:48:23:48:23 | a |
| simple.cpp:26:15:26:15 | f [a_] | simple.cpp:28:10:28:10 | f [a_] |
| simple.cpp:26:15:26:15 | f [b_] | simple.cpp:29:10:29:10 | f [b_] |
| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:28:12:28:12 | call to a |
| simple.cpp:29:10:29:10 | f [b_] | simple.cpp:29:12:29:12 | call to b |
| simple.cpp:39:5:39:5 | ref arg f [a_] | simple.cpp:45:9:45:9 | f [a_] |
| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:39:5:39:5 | ref arg f [a_] |
| simple.cpp:40:5:40:5 | ref arg g [b_] | simple.cpp:48:9:48:9 | g [b_] |
| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:40:5:40:5 | ref arg g [b_] |
| simple.cpp:41:5:41:5 | ref arg h [a_] | simple.cpp:51:9:51:9 | h [a_] |
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:41:5:41:5 | ref arg h [a_] |
| simple.cpp:42:5:42:5 | ref arg h [b_] | simple.cpp:51:9:51:9 | h [b_] |
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:42:5:42:5 | ref arg h [b_] |
| simple.cpp:45:9:45:9 | f [a_] | simple.cpp:26:15:26:15 | f [a_] |
| simple.cpp:48:9:48:9 | g [b_] | simple.cpp:26:15:26:15 | f [b_] |
| simple.cpp:51:9:51:9 | h [a_] | simple.cpp:26:15:26:15 | f [a_] |
| simple.cpp:51:9:51:9 | h [b_] | simple.cpp:26:15:26:15 | f [b_] |
| simple.cpp:65:5:65:5 | a [post update] [i] | simple.cpp:67:10:67:11 | a2 [i] |
| simple.cpp:65:5:65:22 | ... = ... | simple.cpp:65:5:65:5 | a [post update] [i] |
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | ... = ... |
| simple.cpp:67:10:67:11 | a2 [i] | simple.cpp:67:13:67:13 | i |
| simple.cpp:83:9:83:10 | f2 [post update] [f1] | simple.cpp:83:9:83:10 | this [post update] [f2, f1] |
| simple.cpp:83:9:83:10 | this [post update] [f2, f1] | simple.cpp:84:14:84:20 | this [f2, f1] |
| simple.cpp:83:9:83:28 | ... = ... | simple.cpp:83:9:83:10 | f2 [post update] [f1] |
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | ... = ... |
| simple.cpp:84:14:84:20 | this [f2, f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
| struct_init.c:14:24:14:25 | ab [a] | struct_init.c:15:8:15:9 | ab [a] |
| struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a |
| struct_init.c:20:17:20:36 | {...} [a] | struct_init.c:22:8:22:9 | ab [a] |
| struct_init.c:20:17:20:36 | {...} [a] | struct_init.c:24:10:24:12 | & ... [a] |
| struct_init.c:20:17:20:36 | {...} [a] | struct_init.c:28:5:28:7 | & ... [a] |
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:17:20:36 | {...} [a] |
| struct_init.c:22:8:22:9 | ab [a] | struct_init.c:22:11:22:11 | a |
| struct_init.c:24:10:24:12 | & ... [a] | struct_init.c:14:24:14:25 | ab [a] |
| struct_init.c:26:23:29:3 | {...} [nestedAB, a] | struct_init.c:31:8:31:12 | outer [nestedAB, a] |
| struct_init.c:26:23:29:3 | {...} [nestedAB, a] | struct_init.c:36:11:36:15 | outer [nestedAB, a] |
| struct_init.c:26:23:29:3 | {...} [pointerAB, a] | struct_init.c:33:8:33:12 | outer [pointerAB, a] |
| struct_init.c:27:5:27:23 | {...} [a] | struct_init.c:26:23:29:3 | {...} [nestedAB, a] |
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:27:5:27:23 | {...} [a] |
| struct_init.c:28:5:28:7 | & ... [a] | struct_init.c:26:23:29:3 | {...} [pointerAB, a] |
| struct_init.c:31:8:31:12 | outer [nestedAB, a] | struct_init.c:31:14:31:21 | nestedAB [a] |
| struct_init.c:31:14:31:21 | nestedAB [a] | struct_init.c:31:23:31:23 | a |
| struct_init.c:33:8:33:12 | outer [pointerAB, a] | struct_init.c:33:14:33:22 | pointerAB [a] |
| struct_init.c:33:14:33:22 | pointerAB [a] | struct_init.c:33:25:33:25 | a |
| struct_init.c:36:10:36:24 | & ... [a] | struct_init.c:14:24:14:25 | ab [a] |
| struct_init.c:36:11:36:15 | outer [nestedAB, a] | struct_init.c:36:17:36:24 | nestedAB [a] |
| struct_init.c:36:17:36:24 | nestedAB [a] | struct_init.c:36:10:36:24 | & ... [a] |
| struct_init.c:40:17:40:36 | {...} [a] | struct_init.c:43:5:43:7 | & ... [a] |
| struct_init.c:40:20:40:29 | call to user_input | struct_init.c:40:17:40:36 | {...} [a] |
| struct_init.c:41:23:44:3 | {...} [pointerAB, a] | struct_init.c:46:10:46:14 | outer [pointerAB, a] |
| struct_init.c:43:5:43:7 | & ... [a] | struct_init.c:41:23:44:3 | {...} [pointerAB, a] |
| struct_init.c:46:10:46:14 | outer [pointerAB, a] | struct_init.c:46:16:46:24 | pointerAB [a] |
| struct_init.c:46:16:46:24 | pointerAB [a] | struct_init.c:14:24:14:25 | ab [a] |
nodes
| A.cpp:41:15:41:21 | new | semmle.label | new |
| A.cpp:43:10:43:12 | & ... | semmle.label | & ... |
| A.cpp:47:12:47:18 | new | semmle.label | new |
| A.cpp:48:12:48:18 | call to make [c] | semmle.label | call to make [c] |
| A.cpp:48:20:48:20 | c | semmle.label | c |
| A.cpp:49:10:49:10 | b [c] | semmle.label | b [c] |
| A.cpp:49:13:49:13 | c | semmle.label | c |
| A.cpp:55:5:55:5 | ref arg b [c] | semmle.label | ref arg b [c] |
| A.cpp:55:12:55:19 | new | semmle.label | new |
| A.cpp:56:10:56:10 | b [c] | semmle.label | b [c] |
| A.cpp:56:13:56:15 | call to get | semmle.label | call to get |
| A.cpp:57:11:57:24 | call to B [c] | semmle.label | call to B [c] |
| A.cpp:57:11:57:24 | new [c] | semmle.label | new [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:64:10:64:15 | call to setOnB [c] | semmle.label | call to setOnB [c] |
| A.cpp:64:21:64:28 | new | semmle.label | new |
| A.cpp:66:10:66:11 | b2 [c] | semmle.label | b2 [c] |
| A.cpp:66:14:66:14 | c | semmle.label | c |
| A.cpp:73:10:73:19 | call to setOnBWrap [c] | semmle.label | call to setOnBWrap [c] |
| A.cpp:73:25:73:32 | new | semmle.label | new |
| A.cpp:75:10:75:11 | b2 [c] | semmle.label | b2 [c] |
| A.cpp:75:14:75:14 | c | semmle.label | c |
| A.cpp:98:12:98:18 | new | semmle.label | new |
| A.cpp:100:5:100:6 | c1 [post update] [a] | semmle.label | c1 [post update] [a] |
| A.cpp:100:5:100:13 | ... = ... | semmle.label | ... = ... |
| A.cpp:101:8:101:9 | c1 [a] | semmle.label | c1 [a] |
| A.cpp:103:14:103:14 | c [a] | semmle.label | c [a] |
| A.cpp:107:12:107:13 | c1 [a] | semmle.label | c1 [a] |
| A.cpp:107:16:107:16 | a | semmle.label | a |
| A.cpp:120:12:120:13 | c1 [a] | semmle.label | c1 [a] |
| A.cpp:120:16:120:16 | a | semmle.label | a |
| A.cpp:126:5:126:5 | ref arg b [c] | semmle.label | ref arg b [c] |
| A.cpp:126:12:126:18 | new | semmle.label | new |
| A.cpp:131:8:131:8 | ref arg b [c] | semmle.label | ref arg b [c] |
| A.cpp:132:10:132:10 | b [c] | semmle.label | b [c] |
| A.cpp:132:13:132:13 | c | semmle.label | c |
| A.cpp:142:7:142:7 | b [post update] [c] | semmle.label | b [post update] [c] |
| A.cpp:142:7:142:20 | ... = ... | semmle.label | ... = ... |
| A.cpp:142:14:142:20 | new | semmle.label | new |
| A.cpp:143:7:143:10 | this [post update] [b, c] | semmle.label | this [post update] [b, c] |
| A.cpp:143:7:143:10 | this [post update] [b] | semmle.label | this [post update] [b] |
| A.cpp:143:7:143:31 | ... = ... | semmle.label | ... = ... |
| A.cpp:143:7:143:31 | ... = ... [c] | semmle.label | ... = ... [c] |
| A.cpp:143:25:143:31 | new | semmle.label | new |
| A.cpp:150:12:150:18 | new | semmle.label | new |
| A.cpp:151:12:151:24 | call to D [b, c] | semmle.label | call to D [b, c] |
| A.cpp:151:12:151:24 | call to D [b] | semmle.label | call to D [b] |
| A.cpp:151:18:151:18 | b | semmle.label | b |
| A.cpp:151:18:151:18 | ref arg b [c] | semmle.label | ref arg b [c] |
| A.cpp:152:10:152:10 | d [b] | semmle.label | d [b] |
| A.cpp:152:13:152:13 | b | semmle.label | b |
| A.cpp:153:10:153:10 | d [b, c] | semmle.label | d [b, c] |
| A.cpp:153:13:153:13 | b [c] | semmle.label | b [c] |
| A.cpp:153:16:153:16 | c | semmle.label | c |
| A.cpp:154:10:154:10 | b [c] | semmle.label | b [c] |
| A.cpp:154:13:154:13 | c | semmle.label | c |
| A.cpp:159:12:159:18 | new | semmle.label | new |
| A.cpp:160:18:160:60 | call to MyList [head] | semmle.label | call to MyList [head] |
| A.cpp:160:29:160:29 | b | semmle.label | b |
| A.cpp:161:18:161:40 | call to MyList [next, head] | semmle.label | call to MyList [next, head] |
| A.cpp:161:38:161:39 | l1 [head] | semmle.label | l1 [head] |
| A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] | semmle.label | call to MyList [next, next, ... (3)] |
| A.cpp:162:38:162:39 | l2 [next, head] | semmle.label | l2 [next, head] |
| A.cpp:165:10:165:11 | l3 [next, next, ... (3)] | semmle.label | l3 [next, next, ... (3)] |
| A.cpp:165:14:165:17 | next [next, head] | semmle.label | next [next, head] |
| A.cpp:165:20:165:23 | next [head] | semmle.label | next [head] |
| A.cpp:165:26:165:29 | head | semmle.label | head |
| A.cpp:167:44:167:44 | l [next, head] | semmle.label | l [next, head] |
| A.cpp:167:44:167:44 | l [next, next, ... (3)] | semmle.label | l [next, next, ... (3)] |
| A.cpp:167:47:167:50 | next [head] | semmle.label | next [head] |
| A.cpp:167:47:167:50 | next [next, head] | semmle.label | next [next, head] |
| A.cpp:169:12:169:12 | l [head] | semmle.label | l [head] |
| A.cpp:169:15:169:18 | head | semmle.label | head |
| B.cpp:6:15:6:24 | new | semmle.label | new |
| B.cpp:7:16:7:35 | call to Box1 [elem1] | semmle.label | call to Box1 [elem1] |
| B.cpp:7:25:7:25 | e | semmle.label | e |
| B.cpp:8:16:8:27 | call to Box2 [box1, elem1] | semmle.label | call to Box2 [box1, elem1] |
| B.cpp:8:25:8:26 | b1 [elem1] | semmle.label | b1 [elem1] |
| B.cpp:9:10:9:11 | b2 [box1, elem1] | semmle.label | b2 [box1, elem1] |
| B.cpp:9:14:9:17 | box1 [elem1] | semmle.label | box1 [elem1] |
| B.cpp:9:20:9:24 | elem1 | semmle.label | elem1 |
| B.cpp:15:15:15:27 | new | semmle.label | new |
| B.cpp:16:16:16:38 | call to Box1 [elem2] | semmle.label | call to Box1 [elem2] |
| B.cpp:16:37:16:37 | e | semmle.label | e |
| B.cpp:17:16:17:27 | call to Box2 [box1, elem2] | semmle.label | call to Box2 [box1, elem2] |
| B.cpp:17:25:17:26 | b1 [elem2] | semmle.label | b1 [elem2] |
| B.cpp:19:10:19:11 | b2 [box1, elem2] | semmle.label | b2 [box1, elem2] |
| B.cpp:19:14:19:17 | box1 [elem2] | semmle.label | box1 [elem2] |
| B.cpp:19:20:19:24 | elem2 | semmle.label | elem2 |
| C.cpp:18:12:18:18 | call to C [s1] | semmle.label | call to C [s1] |
| C.cpp:18:12:18:18 | call to C [s3] | semmle.label | call to C [s3] |
| C.cpp:19:5:19:5 | c [s1] | semmle.label | c [s1] |
| C.cpp:19:5:19:5 | c [s3] | semmle.label | c [s3] |
| C.cpp:22:9:22:22 | constructor init of field s1 [post-this] [s1] | semmle.label | constructor init of field s1 [post-this] [s1] |
| C.cpp:22:12:22:21 | new | semmle.label | new |
| C.cpp:24:5:24:8 | this [post update] [s3] | semmle.label | this [post update] [s3] |
| C.cpp:24:5:24:25 | ... = ... | semmle.label | ... = ... |
| C.cpp:24:16:24:25 | new | semmle.label | new |
| C.cpp:27:8:27:11 | this [s1] | semmle.label | this [s1] |
| C.cpp:27:8:27:11 | this [s3] | semmle.label | this [s3] |
| C.cpp:29:10:29:11 | s1 | semmle.label | s1 |
| C.cpp:29:10:29:11 | this [s1] | semmle.label | this [s1] |
| C.cpp:31:10:31:11 | s3 | semmle.label | s3 |
| C.cpp:31:10:31:11 | this [s3] | semmle.label | this [s3] |
| D.cpp:21:30:21:31 | b2 [box, elem] | semmle.label | b2 [box, elem] |
| D.cpp:22:10:22:11 | b2 [box, elem] | semmle.label | b2 [box, elem] |
| D.cpp:22:14:22:20 | call to getBox1 [elem] | semmle.label | call to getBox1 [elem] |
| D.cpp:22:25:22:31 | call to getElem | semmle.label | call to getElem |
| D.cpp:28:15:28:24 | new | semmle.label | new |
| D.cpp:30:5:30:5 | b [post update] [box, elem] | semmle.label | b [post update] [box, elem] |
| D.cpp:30:5:30:20 | ... = ... | semmle.label | ... = ... |
| D.cpp:30:8:30:10 | box [post update] [elem] | semmle.label | box [post update] [elem] |
| D.cpp:31:14:31:14 | b [box, elem] | semmle.label | b [box, elem] |
| D.cpp:35:15:35:24 | new | semmle.label | new |
| D.cpp:37:5:37:5 | b [post update] [box, elem] | semmle.label | b [post update] [box, elem] |
| D.cpp:37:8:37:10 | ref arg box [elem] | semmle.label | ref arg box [elem] |
| D.cpp:37:21:37:21 | e | semmle.label | e |
| D.cpp:38:14:38:14 | b [box, elem] | semmle.label | b [box, elem] |
| D.cpp:42:15:42:24 | new | semmle.label | new |
| D.cpp:44:5:44:5 | ref arg b [box, elem] | semmle.label | ref arg b [box, elem] |
| D.cpp:44:5:44:26 | ... = ... | semmle.label | ... = ... |
| D.cpp:44:8:44:14 | call to getBox1 [post update] [elem] | semmle.label | call to getBox1 [post update] [elem] |
| D.cpp:45:14:45:14 | b [box, elem] | semmle.label | b [box, elem] |
| D.cpp:49:15:49:24 | new | semmle.label | new |
| D.cpp:51:5:51:5 | ref arg b [box, elem] | semmle.label | ref arg b [box, elem] |
| D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] | semmle.label | ref arg call to getBox1 [elem] |
| D.cpp:51:27:51:27 | e | semmle.label | e |
| D.cpp:52:14:52:14 | b [box, elem] | semmle.label | b [box, elem] |
| D.cpp:56:15:56:24 | new | semmle.label | new |
| D.cpp:58:5:58:12 | boxfield [post update] [box, elem] | semmle.label | boxfield [post update] [box, elem] |
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] | semmle.label | this [post update] [boxfield, box, ... (3)] |
| D.cpp:58:5:58:27 | ... = ... | semmle.label | ... = ... |
| D.cpp:58:15:58:17 | box [post update] [elem] | semmle.label | box [post update] [elem] |
| D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
| D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
| D.cpp:64:10:64:17 | boxfield [box, elem] | semmle.label | boxfield [box, elem] |
| D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
| D.cpp:64:20:64:22 | box [elem] | semmle.label | box [elem] |
| D.cpp:64:25:64:28 | elem | semmle.label | elem |
| E.cpp:19:27:19:27 | p [data, buffer] | semmle.label | p [data, buffer] |
| E.cpp:21:10:21:10 | p [data, buffer] | semmle.label | p [data, buffer] |
| E.cpp:21:13:21:16 | data [buffer] | semmle.label | data [buffer] |
| E.cpp:21:18:21:23 | buffer | semmle.label | buffer |
| E.cpp:28:21:28:23 | ref arg raw | semmle.label | ref arg raw |
| E.cpp:29:21:29:21 | b [post update] [buffer] | semmle.label | b [post update] [buffer] |
| E.cpp:29:24:29:29 | ref arg buffer | semmle.label | ref arg buffer |
| E.cpp:30:21:30:21 | p [post update] [data, buffer] | semmle.label | p [post update] [data, buffer] |
| E.cpp:30:23:30:26 | data [post update] [buffer] | semmle.label | data [post update] [buffer] |
| E.cpp:30:28:30:33 | ref arg buffer | semmle.label | ref arg buffer |
| E.cpp:31:10:31:12 | raw | semmle.label | raw |
| E.cpp:32:10:32:10 | b [buffer] | semmle.label | b [buffer] |
| E.cpp:32:13:32:18 | buffer | semmle.label | buffer |
| E.cpp:33:18:33:19 | & ... [data, buffer] | semmle.label | & ... [data, buffer] |
| aliasing.cpp:9:3:9:3 | s [post update] [m1] | semmle.label | s [post update] [m1] |
| aliasing.cpp:9:3:9:22 | ... = ... | semmle.label | ... = ... |
| aliasing.cpp:9:11:9:20 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:12:25:12:25 | s [m1] | semmle.label | s [m1] |
| aliasing.cpp:13:3:13:3 | s [post update] [m1] | semmle.label | s [post update] [m1] |
| aliasing.cpp:13:3:13:21 | ... = ... | semmle.label | ... = ... |
| aliasing.cpp:13:10:13:19 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:25:17:25:19 | ref arg & ... [m1] | semmle.label | ref arg & ... [m1] |
| aliasing.cpp:26:19:26:20 | ref arg s2 [m1] | semmle.label | ref arg s2 [m1] |
| aliasing.cpp:29:8:29:9 | s1 [m1] | semmle.label | s1 [m1] |
| aliasing.cpp:29:11:29:12 | m1 | semmle.label | m1 |
| aliasing.cpp:30:8:30:9 | s2 [m1] | semmle.label | s2 [m1] |
| aliasing.cpp:30:11:30:12 | m1 | semmle.label | m1 |
| aliasing.cpp:60:3:60:4 | s2 [post update] [m1] | semmle.label | s2 [post update] [m1] |
| aliasing.cpp:60:3:60:22 | ... = ... | semmle.label | ... = ... |
| aliasing.cpp:60:11:60:20 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:62:8:62:12 | copy2 [m1] | semmle.label | copy2 [m1] |
| aliasing.cpp:62:14:62:15 | m1 | semmle.label | m1 |
| aliasing.cpp:92:3:92:3 | w [post update] [s, m1] | semmle.label | w [post update] [s, m1] |
| aliasing.cpp:92:3:92:23 | ... = ... | semmle.label | ... = ... |
| aliasing.cpp:92:5:92:5 | s [post update] [m1] | semmle.label | s [post update] [m1] |
| aliasing.cpp:92:12:92:21 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:93:8:93:8 | w [s, m1] | semmle.label | w [s, m1] |
| aliasing.cpp:93:10:93:10 | s [m1] | semmle.label | s [m1] |
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
| by_reference.cpp:50:3:50:3 | ref arg s [a] | semmle.label | ref arg s [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 | s [a] | semmle.label | s [a] |
| by_reference.cpp:51:10:51:20 | call to getDirectly | semmle.label | call to getDirectly |
| by_reference.cpp:56:3:56:3 | ref arg s [a] | semmle.label | ref arg s [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 | s [a] | semmle.label | s [a] |
| by_reference.cpp:57:10:57:22 | call to getIndirectly | semmle.label | call to getIndirectly |
| by_reference.cpp:62:3:62:3 | ref arg s [a] | semmle.label | ref arg s [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 | s [a] | semmle.label | s [a] |
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | semmle.label | call to getThroughNonMember |
| by_reference.cpp:68:17:68:18 | ref arg & ... [a] | semmle.label | ref arg & ... [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 | & ... [a] | semmle.label | & ... [a] |
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | semmle.label | inner [post update] [a] |
| by_reference.cpp:84:3:84:25 | ... = ... | semmle.label | ... = ... |
| by_reference.cpp:84:14:84:23 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:87:31:87:35 | inner [a] | semmle.label | inner [a] |
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | semmle.label | inner [post update] [a] |
| by_reference.cpp:88:3:88:24 | ... = ... | semmle.label | ... = ... |
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:95:25:95:26 | pa | semmle.label | pa |
| by_reference.cpp:96:8:96:17 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:102:21:102:39 | ref arg & ... [a] | semmle.label | ref arg & ... [a] |
| by_reference.cpp:102:22:102:26 | outer [post update] [inner_nested, a] | semmle.label | outer [post update] [inner_nested, a] |
| by_reference.cpp:102:28:102:39 | inner_nested [inner post update] [a] | semmle.label | inner_nested [inner post update] [a] |
| by_reference.cpp:103:21:103:25 | outer [post update] [inner_ptr, a] | semmle.label | outer [post update] [inner_ptr, a] |
| by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] | semmle.label | ref arg inner_ptr [a] |
| by_reference.cpp:106:21:106:41 | ref arg & ... [a] | semmle.label | ref arg & ... [a] |
| by_reference.cpp:106:22:106:27 | pouter [post update] [inner_nested, a] | semmle.label | pouter [post update] [inner_nested, a] |
| by_reference.cpp:106:30:106:41 | inner_nested [inner post update] [a] | semmle.label | inner_nested [inner post update] [a] |
| by_reference.cpp:107:21:107:26 | pouter [post update] [inner_ptr, a] | semmle.label | pouter [post update] [inner_ptr, a] |
| by_reference.cpp:107:29:107:37 | ref arg inner_ptr [a] | semmle.label | ref arg inner_ptr [a] |
| by_reference.cpp:110:8:110:12 | outer [inner_nested, a] | semmle.label | outer [inner_nested, a] |
| by_reference.cpp:110:14:110:25 | inner_nested [a] | semmle.label | inner_nested [a] |
| by_reference.cpp:110:27:110:27 | a | semmle.label | a |
| by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] | semmle.label | outer [inner_ptr, a] |
| by_reference.cpp:111:14:111:22 | inner_ptr [a] | semmle.label | inner_ptr [a] |
| by_reference.cpp:111:25:111:25 | a | semmle.label | a |
| by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] | semmle.label | pouter [inner_nested, a] |
| by_reference.cpp:114:16:114:27 | inner_nested [a] | semmle.label | inner_nested [a] |
| by_reference.cpp:114:29:114:29 | a | semmle.label | a |
| by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] | semmle.label | pouter [inner_ptr, a] |
| by_reference.cpp:115:16:115:24 | inner_ptr [a] | semmle.label | inner_ptr [a] |
| by_reference.cpp:115:27:115:27 | a | semmle.label | a |
| by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] | semmle.label | outer [post update] [inner_nested, a] |
| by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] | semmle.label | ref arg inner_nested [a] |
| by_reference.cpp:123:21:123:36 | ref arg * ... [a] | semmle.label | ref arg * ... [a] |
| by_reference.cpp:123:22:123:26 | outer [post update] [inner_ptr, a] | semmle.label | outer [post update] [inner_ptr, a] |
| by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] [a] | semmle.label | inner_ptr [inner post update] [a] |
| by_reference.cpp:124:15:124:19 | outer [post update] [a] | semmle.label | outer [post update] [a] |
| by_reference.cpp:124:21:124:21 | ref arg a | semmle.label | ref arg a |
| by_reference.cpp:126:21:126:26 | pouter [post update] [inner_nested, a] | semmle.label | pouter [post update] [inner_nested, a] |
| by_reference.cpp:126:29:126:40 | ref arg inner_nested [a] | semmle.label | ref arg inner_nested [a] |
| by_reference.cpp:127:21:127:38 | ref arg * ... [a] | semmle.label | ref arg * ... [a] |
| by_reference.cpp:127:22:127:27 | pouter [post update] [inner_ptr, a] | semmle.label | pouter [post update] [inner_ptr, a] |
| by_reference.cpp:127:30:127:38 | inner_ptr [inner post update] [a] | semmle.label | inner_ptr [inner post update] [a] |
| by_reference.cpp:128:15:128:20 | pouter [post update] [a] | semmle.label | pouter [post update] [a] |
| by_reference.cpp:128:23:128:23 | ref arg a | semmle.label | ref arg a |
| by_reference.cpp:130:8:130:12 | outer [inner_nested, a] | semmle.label | outer [inner_nested, a] |
| by_reference.cpp:130:14:130:25 | inner_nested [a] | semmle.label | inner_nested [a] |
| by_reference.cpp:130:27:130:27 | a | semmle.label | a |
| by_reference.cpp:131:8:131:12 | outer [inner_ptr, a] | semmle.label | outer [inner_ptr, a] |
| by_reference.cpp:131:14:131:22 | inner_ptr [a] | semmle.label | inner_ptr [a] |
| by_reference.cpp:131:25:131:25 | a | semmle.label | a |
| by_reference.cpp:132:8:132:12 | outer [a] | semmle.label | outer [a] |
| by_reference.cpp:132:14:132:14 | a | semmle.label | a |
| by_reference.cpp:134:8:134:13 | pouter [inner_nested, a] | semmle.label | pouter [inner_nested, a] |
| by_reference.cpp:134:16:134:27 | inner_nested [a] | semmle.label | inner_nested [a] |
| by_reference.cpp:134:29:134:29 | a | semmle.label | a |
| by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | semmle.label | pouter [inner_ptr, a] |
| by_reference.cpp:135:16:135:24 | inner_ptr [a] | semmle.label | inner_ptr [a] |
| by_reference.cpp:135:27:135:27 | a | semmle.label | a |
| by_reference.cpp:136:8:136:13 | pouter [a] | semmle.label | pouter [a] |
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
| complex.cpp:34:15:34:15 | b [f, a_] | semmle.label | b [f, a_] |
| complex.cpp:34:15:34:15 | b [f, b_] | semmle.label | b [f, b_] |
| complex.cpp:44:8:44:8 | b [f, a_] | semmle.label | b [f, a_] |
| complex.cpp:44:10:44:10 | f [a_] | semmle.label | f [a_] |
| complex.cpp:44:12:44:12 | call to a | semmle.label | call to a |
| complex.cpp:45:8:45:8 | b [f, b_] | semmle.label | b [f, b_] |
| complex.cpp:45:10:45:10 | f [b_] | semmle.label | f [b_] |
| complex.cpp:45:12:45:12 | call to b | semmle.label | call to b |
| complex.cpp:55:3:55:4 | b1 [post update] [f, a_] | semmle.label | b1 [post update] [f, a_] |
| complex.cpp:55:6:55:6 | ref arg f [a_] | semmle.label | ref arg f [a_] |
| complex.cpp:55:13:55:22 | call to user_input | semmle.label | call to user_input |
| complex.cpp:56:3:56:4 | b2 [post update] [f, b_] | semmle.label | b2 [post update] [f, b_] |
| complex.cpp:56:6:56:6 | ref arg f [b_] | semmle.label | ref arg f [b_] |
| complex.cpp:56:13:56:22 | call to user_input | semmle.label | call to user_input |
| complex.cpp:57:3:57:4 | b3 [post update] [f, a_] | semmle.label | b3 [post update] [f, a_] |
| complex.cpp:57:6:57:6 | ref arg f [a_] | semmle.label | ref arg f [a_] |
| complex.cpp:57:13:57:22 | call to user_input | semmle.label | call to user_input |
| complex.cpp:58:3:58:4 | b3 [post update] [f, b_] | semmle.label | b3 [post update] [f, b_] |
| complex.cpp:58:6:58:6 | ref arg f [b_] | semmle.label | ref arg f [b_] |
| complex.cpp:58:13:58:22 | call to user_input | semmle.label | call to user_input |
| complex.cpp:61:7:61:8 | b1 [f, a_] | semmle.label | b1 [f, a_] |
| complex.cpp:64:7:64:8 | b2 [f, b_] | semmle.label | b2 [f, b_] |
| complex.cpp:67:7:67:8 | b3 [f, a_] | semmle.label | b3 [f, a_] |
| complex.cpp:67:7:67:8 | b3 [f, b_] | semmle.label | b3 [f, 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 | f [a_] | semmle.label | f [a_] |
| constructors.cpp:28:12:28:12 | call to a | semmle.label | call to a |
| constructors.cpp:29:10:29:10 | f [b_] | semmle.label | f [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 | call to Foo [a_] | semmle.label | call to Foo [a_] |
| constructors.cpp:35:11:35:26 | call to Foo [b_] | semmle.label | call to Foo [b_] |
| constructors.cpp:35:14:35:23 | call to user_input | semmle.label | call to user_input |
| constructors.cpp:36:11:36:20 | call to user_input | semmle.label | call to user_input |
| constructors.cpp:36:11:36:37 | call to Foo [a_] | semmle.label | call to Foo [a_] |
| constructors.cpp:36:11:36:37 | call to Foo [b_] | semmle.label | call to Foo [b_] |
| constructors.cpp:36:25:36:34 | call to user_input | semmle.label | call to user_input |
| constructors.cpp:40:9:40:9 | f [a_] | semmle.label | f [a_] |
| constructors.cpp:43:9:43:9 | g [b_] | semmle.label | g [b_] |
| constructors.cpp:46:9:46:9 | h [a_] | semmle.label | h [a_] |
| constructors.cpp:46:9:46:9 | h [b_] | semmle.label | h [b_] |
| qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
| qualifiers.cpp:22:5:22:38 | ... = ... | semmle.label | ... = ... |
| qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] | semmle.label | call to getInner [post update] [a] |
| qualifiers.cpp:22:27:22:36 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:23:10:23:14 | outer [inner, a] | semmle.label | outer [inner, a] |
| qualifiers.cpp:23:16:23:20 | inner [a] | semmle.label | inner [a] |
| qualifiers.cpp:23:23:23:23 | a | semmle.label | a |
| qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
| qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] | semmle.label | ref arg call to getInner [a] |
| qualifiers.cpp:27:28:27:37 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:28:10:28:14 | outer [inner, a] | semmle.label | outer [inner, a] |
| qualifiers.cpp:28:16:28:20 | inner [a] | semmle.label | inner [a] |
| qualifiers.cpp:28:23:28:23 | a | semmle.label | a |
| qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
| qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] | semmle.label | ref arg call to getInner [a] |
| qualifiers.cpp:32:35:32:44 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:33:10:33:14 | outer [inner, a] | semmle.label | outer [inner, a] |
| qualifiers.cpp:33:16:33:20 | inner [a] | semmle.label | inner [a] |
| qualifiers.cpp:33:23:33:23 | a | semmle.label | a |
| qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | semmle.label | ref arg * ... [a] |
| qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
| qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] | semmle.label | call to getInner [inner post update] [a] |
| qualifiers.cpp:37:38:37:47 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:38:10:38:14 | outer [inner, a] | semmle.label | outer [inner, a] |
| qualifiers.cpp:38:16:38:20 | inner [a] | semmle.label | inner [a] |
| qualifiers.cpp:38:23:38:23 | a | semmle.label | a |
| qualifiers.cpp:42:5:42:40 | ... = ... | semmle.label | ... = ... |
| qualifiers.cpp:42:6:42:22 | * ... [post update] [a] | semmle.label | * ... [post update] [a] |
| qualifiers.cpp:42:7:42:11 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
| qualifiers.cpp:42:13:42:20 | call to getInner [inner post update] [a] | semmle.label | call to getInner [inner post update] [a] |
| qualifiers.cpp:42:29:42:38 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:43:10:43:14 | outer [inner, a] | semmle.label | outer [inner, a] |
| qualifiers.cpp:43:16:43:20 | inner [a] | semmle.label | inner [a] |
| qualifiers.cpp:43:23:43:23 | a | semmle.label | a |
| qualifiers.cpp:47:5:47:42 | ... = ... | semmle.label | ... = ... |
| qualifiers.cpp:47:6:47:11 | ref arg & ... [inner, a] | semmle.label | ref arg & ... [inner, a] |
| qualifiers.cpp:47:15:47:22 | call to getInner [post update] [a] | semmle.label | call to getInner [post update] [a] |
| qualifiers.cpp:47:31:47:40 | call to user_input | semmle.label | call to user_input |
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | semmle.label | outer [inner, a] |
| qualifiers.cpp:48:16:48:20 | inner [a] | semmle.label | inner [a] |
| qualifiers.cpp:48:23:48:23 | a | semmle.label | a |
| 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 | f [a_] | semmle.label | f [a_] |
| simple.cpp:28:12:28:12 | call to a | semmle.label | call to a |
| simple.cpp:29:10:29:10 | f [b_] | semmle.label | f [b_] |
| simple.cpp:29:12:29:12 | call to b | semmle.label | call to b |
| simple.cpp:39:5:39:5 | ref arg f [a_] | semmle.label | ref arg f [a_] |
| simple.cpp:39:12:39:21 | call to user_input | semmle.label | call to user_input |
| simple.cpp:40:5:40:5 | ref arg g [b_] | semmle.label | ref arg g [b_] |
| simple.cpp:40:12:40:21 | call to user_input | semmle.label | call to user_input |
| simple.cpp:41:5:41:5 | ref arg h [a_] | semmle.label | ref arg h [a_] |
| simple.cpp:41:12:41:21 | call to user_input | semmle.label | call to user_input |
| simple.cpp:42:5:42:5 | ref arg h [b_] | semmle.label | ref arg h [b_] |
| simple.cpp:42:12:42:21 | call to user_input | semmle.label | call to user_input |
| simple.cpp:45:9:45:9 | f [a_] | semmle.label | f [a_] |
| simple.cpp:48:9:48:9 | g [b_] | semmle.label | g [b_] |
| simple.cpp:51:9:51:9 | h [a_] | semmle.label | h [a_] |
| simple.cpp:51:9:51:9 | h [b_] | semmle.label | h [b_] |
| simple.cpp:65:5:65:5 | a [post update] [i] | semmle.label | a [post update] [i] |
| simple.cpp:65:5:65:22 | ... = ... | semmle.label | ... = ... |
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
| simple.cpp:67:10:67:11 | a2 [i] | semmle.label | a2 [i] |
| simple.cpp:67:13:67:13 | i | semmle.label | i |
| simple.cpp:83:9:83:10 | f2 [post update] [f1] | semmle.label | f2 [post update] [f1] |
| simple.cpp:83:9:83:10 | this [post update] [f2, f1] | semmle.label | this [post update] [f2, f1] |
| simple.cpp:83:9:83:28 | ... = ... | semmle.label | ... = ... |
| simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input |
| simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 |
| simple.cpp:84:14:84:20 | this [f2, f1] | semmle.label | this [f2, f1] |
| struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] |
| struct_init.c:15:8:15:9 | ab [a] | semmle.label | ab [a] |
| struct_init.c:15:12:15:12 | a | semmle.label | a |
| struct_init.c:20:17:20:36 | {...} [a] | semmle.label | {...} [a] |
| struct_init.c:20:20:20:29 | call to user_input | semmle.label | call to user_input |
| struct_init.c:22:8:22:9 | ab [a] | semmle.label | ab [a] |
| struct_init.c:22:11:22:11 | a | semmle.label | a |
| struct_init.c:24:10:24:12 | & ... [a] | semmle.label | & ... [a] |
| struct_init.c:26:23:29:3 | {...} [nestedAB, a] | semmle.label | {...} [nestedAB, a] |
| struct_init.c:26:23:29:3 | {...} [pointerAB, a] | semmle.label | {...} [pointerAB, a] |
| struct_init.c:27:5:27:23 | {...} [a] | semmle.label | {...} [a] |
| struct_init.c:27:7:27:16 | call to user_input | semmle.label | call to user_input |
| struct_init.c:28:5:28:7 | & ... [a] | semmle.label | & ... [a] |
| struct_init.c:31:8:31:12 | outer [nestedAB, a] | semmle.label | outer [nestedAB, a] |
| struct_init.c:31:14:31:21 | nestedAB [a] | semmle.label | nestedAB [a] |
| struct_init.c:31:23:31:23 | a | semmle.label | a |
| struct_init.c:33:8:33:12 | outer [pointerAB, a] | semmle.label | outer [pointerAB, a] |
| struct_init.c:33:14:33:22 | pointerAB [a] | semmle.label | pointerAB [a] |
| struct_init.c:33:25:33:25 | a | semmle.label | a |
| struct_init.c:36:10:36:24 | & ... [a] | semmle.label | & ... [a] |
| struct_init.c:36:11:36:15 | outer [nestedAB, a] | semmle.label | outer [nestedAB, a] |
| struct_init.c:36:17:36:24 | nestedAB [a] | semmle.label | nestedAB [a] |
| struct_init.c:40:17:40:36 | {...} [a] | semmle.label | {...} [a] |
| struct_init.c:40:20:40:29 | call to user_input | semmle.label | call to user_input |
| struct_init.c:41:23:44:3 | {...} [pointerAB, a] | semmle.label | {...} [pointerAB, a] |
| struct_init.c:43:5:43:7 | & ... [a] | semmle.label | & ... [a] |
| struct_init.c:46:10:46:14 | outer [pointerAB, a] | semmle.label | outer [pointerAB, a] |
| struct_init.c:46:16:46:24 | pointerAB [a] | semmle.label | pointerAB [a] |
#select
| A.cpp:43:10:43:12 | & ... | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... | & ... flows from $@ | A.cpp:41:15:41:21 | new | new |
| A.cpp:49:13:49:13 | c | A.cpp:47:12:47:18 | new | A.cpp:49:13:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new | new |
| 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 |
| A.cpp:57:28:57:30 | call to get | A.cpp:57:17:57:23 | new | A.cpp:57:28:57:30 | call to get | call to get flows from $@ | A.cpp:57:17:57:23 | new | new |
| A.cpp:66:14:66:14 | c | A.cpp:64:21:64:28 | new | A.cpp:66:14:66:14 | c | c flows from $@ | A.cpp:64:21:64:28 | new | new |
| A.cpp:75:14:75:14 | c | A.cpp:73:25:73:32 | new | A.cpp:75:14:75:14 | c | c flows from $@ | A.cpp:73:25:73:32 | new | new |
| A.cpp:107:16:107:16 | a | A.cpp:98:12:98:18 | new | A.cpp:107:16:107:16 | a | a flows from $@ | A.cpp:98:12:98:18 | new | new |
| A.cpp:120:16:120:16 | a | A.cpp:98:12:98:18 | new | A.cpp:120:16:120:16 | a | a flows from $@ | A.cpp:98:12:98:18 | new | new |
| A.cpp:132:13:132:13 | c | A.cpp:126:12:126:18 | new | A.cpp:132:13:132:13 | c | c flows from $@ | A.cpp:126:12:126:18 | new | new |
| A.cpp:152:13:152:13 | b | A.cpp:143:25:143:31 | new | A.cpp:152:13:152:13 | b | b flows from $@ | A.cpp:143:25:143:31 | new | new |
| A.cpp:152:13:152:13 | b | A.cpp:150:12:150:18 | new | A.cpp:152:13:152:13 | b | b flows from $@ | A.cpp:150:12:150:18 | new | new |
| A.cpp:153:16:153:16 | c | A.cpp:142:14:142:20 | new | A.cpp:153:16:153:16 | c | c flows from $@ | A.cpp:142:14:142:20 | new | new |
| A.cpp:154:13:154:13 | c | A.cpp:142:14:142:20 | new | A.cpp:154:13:154:13 | c | c flows from $@ | A.cpp:142:14:142:20 | new | new |
| A.cpp:165:26:165:29 | head | A.cpp:159:12:159:18 | new | A.cpp:165:26:165:29 | head | head flows from $@ | A.cpp:159:12:159:18 | new | new |
| A.cpp:169:15:169:18 | head | A.cpp:159:12:159:18 | new | A.cpp:169:15:169:18 | head | head flows from $@ | A.cpp:159:12:159:18 | new | new |
| B.cpp:9:20:9:24 | elem1 | B.cpp:6:15:6:24 | new | B.cpp:9:20:9:24 | elem1 | elem1 flows from $@ | B.cpp:6:15:6:24 | new | new |
| B.cpp:19:20:19:24 | elem2 | B.cpp:15:15:15:27 | new | B.cpp:19:20:19:24 | elem2 | elem2 flows from $@ | B.cpp:15:15:15:27 | new | new |
| C.cpp:29:10:29:11 | s1 | C.cpp:22:12:22:21 | new | C.cpp:29:10:29:11 | s1 | s1 flows from $@ | C.cpp:22:12:22:21 | new | new |
| C.cpp:31:10:31:11 | s3 | C.cpp:24:16:24:25 | new | C.cpp:31:10:31:11 | s3 | s3 flows from $@ | C.cpp:24:16:24:25 | new | new |
| D.cpp:22:25:22:31 | call to getElem | D.cpp:28:15:28:24 | new | D.cpp:22:25:22:31 | call to getElem | call to getElem flows from $@ | D.cpp:28:15:28:24 | new | new |
| D.cpp:22:25:22:31 | call to getElem | D.cpp:35:15:35:24 | new | D.cpp:22:25:22:31 | call to getElem | call to getElem flows from $@ | D.cpp:35:15:35:24 | new | new |
| D.cpp:22:25:22:31 | call to getElem | D.cpp:42:15:42:24 | new | D.cpp:22:25:22:31 | call to getElem | call to getElem flows from $@ | D.cpp:42:15:42:24 | new | new |
| D.cpp:22:25:22:31 | call to getElem | D.cpp:49:15:49:24 | new | D.cpp:22:25:22:31 | call to getElem | call to getElem flows from $@ | D.cpp:49:15:49:24 | new | new |
| D.cpp:64:25:64:28 | elem | D.cpp:56:15:56:24 | new | D.cpp:64:25:64:28 | elem | elem flows from $@ | D.cpp:56:15:56:24 | new | new |
| E.cpp:21:18:21:23 | buffer | E.cpp:30:28:30:33 | ref arg buffer | E.cpp:21:18:21:23 | buffer | buffer flows from $@ | E.cpp:30:28:30:33 | ref arg buffer | ref arg buffer |
| E.cpp:31:10:31:12 | raw | E.cpp:28:21:28:23 | ref arg raw | E.cpp:31:10:31:12 | raw | raw flows from $@ | E.cpp:28:21:28:23 | ref arg raw | ref arg raw |
| E.cpp:32:13:32:18 | buffer | E.cpp:29:24:29:29 | ref arg buffer | E.cpp:32:13:32:18 | buffer | buffer flows from $@ | E.cpp:29:24:29:29 | ref arg buffer | ref arg buffer |
| aliasing.cpp:29:11:29:12 | m1 | aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:29:11:29:12 | m1 | m1 flows from $@ | aliasing.cpp:9:11:9:20 | call to user_input | call to user_input |
| aliasing.cpp:30:11:30:12 | m1 | aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:30:11:30:12 | m1 | m1 flows from $@ | aliasing.cpp:13:10:13:19 | call to user_input | call to user_input |
| aliasing.cpp:62:14:62:15 | m1 | aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:62:14:62:15 | m1 | m1 flows from $@ | aliasing.cpp:60:11:60:20 | call to user_input | call to user_input |
| aliasing.cpp:93:12:93:13 | m1 | aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 | m1 flows from $@ | aliasing.cpp:92:12:92:21 | call to user_input | call to user_input |
| by_reference.cpp:51:10:51:20 | call to getDirectly | by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:51:10:51:20 | call to getDirectly | call to getDirectly flows from $@ | by_reference.cpp:50:17:50:26 | call to user_input | call to user_input |
| by_reference.cpp:57:10:57:22 | call to getIndirectly | by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:57:10:57:22 | call to getIndirectly | call to getIndirectly flows from $@ | by_reference.cpp:56:19:56:28 | call to user_input | call to user_input |
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:63:10:63:28 | call to getThroughNonMember | call to getThroughNonMember flows from $@ | by_reference.cpp:62:25:62:34 | call to user_input | call to user_input |
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | call to nonMemberGetA flows from $@ | by_reference.cpp:68:21:68:30 | call to user_input | call to user_input |
| by_reference.cpp:110:27:110:27 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:110:27:110:27 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:111:25:111:25 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:111:25:111:25 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:114:29:114:29 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:114:29:114:29 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:115:27:115:27 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:115:27:115:27 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:130:27:130:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:130:27:130:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:131:25:131:25 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:131:25:131:25 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:132:14:132:14 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:132:14:132:14 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:135:27:135:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:135:27:135:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:136:16:136:16 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
| complex.cpp:44:12:44:12 | call to a | complex.cpp:55:13:55:22 | call to user_input | complex.cpp:44:12:44:12 | call to a | call to a flows from $@ | complex.cpp:55:13:55:22 | call to user_input | call to user_input |
| complex.cpp:44:12:44:12 | call to a | complex.cpp:57:13:57:22 | call to user_input | complex.cpp:44:12:44:12 | call to a | call to a flows from $@ | complex.cpp:57:13:57:22 | call to user_input | call to user_input |
| complex.cpp:45:12:45:12 | call to b | complex.cpp:56:13:56:22 | call to user_input | complex.cpp:45:12:45:12 | call to b | call to b flows from $@ | complex.cpp:56:13:56:22 | call to user_input | call to user_input |
| complex.cpp:45:12:45:12 | call to b | complex.cpp:58:13:58:22 | call to user_input | complex.cpp:45:12:45:12 | call to b | call to b flows from $@ | complex.cpp:58:13:58:22 | call to user_input | call to user_input |
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:34:11:34:20 | call to user_input | call to user_input |
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:36:11:36:20 | call to user_input | call to user_input |
| constructors.cpp:29:12:29:12 | call to b | constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:35:14:35:23 | call to user_input | call to user_input |
| constructors.cpp:29:12:29:12 | call to b | constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:36:25:36:34 | call to user_input | call to user_input |
| qualifiers.cpp:23:23:23:23 | a | qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:23:23:23:23 | a | a flows from $@ | qualifiers.cpp:22:27:22:36 | call to user_input | call to user_input |
| qualifiers.cpp:28:23:28:23 | a | qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:28:23:28:23 | a | a flows from $@ | qualifiers.cpp:27:28:27:37 | call to user_input | call to user_input |
| qualifiers.cpp:33:23:33:23 | a | qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:33:23:33:23 | a | a flows from $@ | qualifiers.cpp:32:35:32:44 | call to user_input | call to user_input |
| qualifiers.cpp:38:23:38:23 | a | qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:38:23:38:23 | a | a flows from $@ | qualifiers.cpp:37:38:37:47 | call to user_input | call to user_input |
| qualifiers.cpp:43:23:43:23 | a | qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:43:23:43:23 | a | a flows from $@ | qualifiers.cpp:42:29:42:38 | call to user_input | call to user_input |
| qualifiers.cpp:48:23:48:23 | a | qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:48:23:48:23 | a | a flows from $@ | qualifiers.cpp:47:31:47:40 | call to user_input | call to user_input |
| simple.cpp:28:12:28:12 | call to a | simple.cpp:39:12:39:21 | call to user_input | simple.cpp:28:12:28:12 | call to a | call to a flows from $@ | simple.cpp:39:12:39:21 | call to user_input | call to user_input |
| simple.cpp:28:12:28:12 | call to a | simple.cpp:41:12:41:21 | call to user_input | simple.cpp:28:12:28:12 | call to a | call to a flows from $@ | simple.cpp:41:12:41:21 | call to user_input | call to user_input |
| simple.cpp:29:12:29:12 | call to b | simple.cpp:40:12:40:21 | call to user_input | simple.cpp:29:12:29:12 | call to b | call to b flows from $@ | simple.cpp:40:12:40:21 | call to user_input | call to user_input |
| simple.cpp:29:12:29:12 | call to b | simple.cpp:42:12:42:21 | call to user_input | simple.cpp:29:12:29:12 | call to b | call to b flows from $@ | simple.cpp:42:12:42:21 | call to user_input | call to user_input |
| simple.cpp:67:13:67:13 | i | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:67:13:67:13 | i | i flows from $@ | simple.cpp:65:11:65:20 | call to user_input | call to user_input |
| simple.cpp:84:14:84:20 | call to getf2f1 | simple.cpp:83:17:83:26 | call to user_input | simple.cpp:84:14:84:20 | call to getf2f1 | call to getf2f1 flows from $@ | simple.cpp:83:17:83:26 | call to user_input | call to user_input |
| struct_init.c:15:12:15:12 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |
| struct_init.c:15:12:15:12 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input |
| struct_init.c:15:12:15:12 | a | struct_init.c:40:20:40:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:40:20:40:29 | call to user_input | call to user_input |
| struct_init.c:22:11:22:11 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:22:11:22:11 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |
| struct_init.c:31:23:31:23 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:31:23:31:23 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input |
| struct_init.c:33:25:33:25 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:33:25:33:25 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |

View File

@@ -1,9 +1,9 @@
/**
* @kind path-problem
* @kind problem
*/
import TestUtilities.InlineExpectationsTest
import semmle.code.cpp.dataflow.DataFlow
import DataFlow::PathGraph
import DataFlow
import cpp
@@ -37,6 +37,28 @@ class Conf extends Configuration {
}
}
from DataFlow::PathNode src, DataFlow::PathNode sink, Conf conf
where conf.hasFlowPath(src, sink)
select sink, src, sink, sink + " flows from $@", src, src.toString()
class ASTFieldFlowTest extends InlineExpectationsTest {
ASTFieldFlowTest() { this = "ASTFieldFlowTest" }
override string getARelevantTag() { result = "ast" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Node source, Node sink, Conf conf, int n |
tag = "ast" and
conf.hasFlow(source, sink) and
n = strictcount(Node otherSource | conf.hasFlow(otherSource, sink)) and
(
n = 1 and value = ""
or
// If there is more than one source for this sink
// we specify the source location explicitly.
n > 1 and
value =
source.getLocation().getStartLine().toString() + ":" +
source.getLocation().getStartColumn()
) and
location = sink.getLocation() and
element = sink.toString()
)
}
}

View File

@@ -1,128 +0,0 @@
edges
| A.cpp:142:7:142:20 | Chi [c] | A.cpp:151:18:151:18 | D output argument [c] |
| A.cpp:142:7:142:20 | Store | A.cpp:142:7:142:20 | Chi [c] |
| A.cpp:142:14:142:20 | new | A.cpp:142:7:142:20 | Store |
| A.cpp:151:18:151:18 | Chi [c] | A.cpp:154:13:154:13 | c |
| 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:154:13:154:13 | c | A.cpp:154:10:154:13 | (void *)... |
| aliasing.cpp:9:3:9:22 | Chi [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] |
| aliasing.cpp:9:3:9:22 | Store | aliasing.cpp:9:3:9:22 | Chi [m1] |
| aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:9:3:9:22 | Store |
| aliasing.cpp:13:3:13:21 | Chi [m1] | aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] |
| aliasing.cpp:13:3:13:21 | Store | aliasing.cpp:13:3:13:21 | Chi [m1] |
| aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:13:3:13:21 | Store |
| aliasing.cpp:25:17:25:19 | Chi [m1] | aliasing.cpp:29:11:29:12 | m1 |
| aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | aliasing.cpp:25:17:25:19 | Chi [m1] |
| aliasing.cpp:26:19:26:20 | Chi [m1] | aliasing.cpp:30:11:30:12 | m1 |
| aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | aliasing.cpp:26:19:26:20 | Chi [m1] |
| aliasing.cpp:37:13:37:22 | call to user_input | aliasing.cpp:38:11:38:12 | m1 |
| aliasing.cpp:42:11:42:20 | call to user_input | aliasing.cpp:43:13:43:14 | m1 |
| aliasing.cpp:60:3:60:22 | Chi [m1] | aliasing.cpp:61:13:61:14 | Store [m1] |
| aliasing.cpp:60:3:60:22 | Store | aliasing.cpp:60:3:60:22 | Chi [m1] |
| aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:60:3:60:22 | Store |
| aliasing.cpp:61:13:61:14 | Store [m1] | aliasing.cpp:62:14:62:15 | m1 |
| aliasing.cpp:79:11:79:20 | call to user_input | aliasing.cpp:80:12:80:13 | m1 |
| aliasing.cpp:86:10:86:19 | call to user_input | aliasing.cpp:87:12:87:13 | m1 |
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 |
| 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] |
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:84:3:84:25 | Store |
| by_reference.cpp:88:3:88:24 | Chi [a] | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] |
| by_reference.cpp:88:3:88:24 | Chi [a] | by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] |
| by_reference.cpp:88:3:88:24 | Store | by_reference.cpp:88:3:88:24 | Chi [a] |
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:3:88:24 | Store |
| by_reference.cpp:102:21:102:39 | Chi [a] | by_reference.cpp:110:27:110:27 | a |
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | by_reference.cpp:102:21:102:39 | Chi [a] |
| by_reference.cpp:106:21:106:41 | Chi [a] | by_reference.cpp:114:29:114:29 | a |
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | by_reference.cpp:106:21:106:41 | Chi [a] |
| by_reference.cpp:122:21:122:38 | Chi [a] | by_reference.cpp:130:27:130:27 | a |
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:21:122:38 | Chi [a] |
| by_reference.cpp:126:21:126:40 | Chi [a] | by_reference.cpp:134:29:134:29 | a |
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | by_reference.cpp:126:21:126:40 | Chi [a] |
| 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 |
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:22:11:22:11 | a |
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:31:23:31:23 | a |
nodes
| A.cpp:142:7:142:20 | Chi [c] | semmle.label | Chi [c] |
| A.cpp:142:7:142:20 | Store | semmle.label | Store |
| A.cpp:142:14:142:20 | new | semmle.label | new |
| 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:154:10:154:13 | (void *)... | semmle.label | (void *)... |
| A.cpp:154:13:154:13 | c | semmle.label | c |
| A.cpp:154:13:154:13 | c | semmle.label | c |
| aliasing.cpp:9:3:9:22 | Chi [m1] | semmle.label | Chi [m1] |
| aliasing.cpp:9:3:9:22 | Store | semmle.label | Store |
| aliasing.cpp:9:11:9:20 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:13:3:13:21 | Chi [m1] | semmle.label | Chi [m1] |
| aliasing.cpp:13:3:13:21 | Store | semmle.label | Store |
| aliasing.cpp:13:10:13:19 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:25:17:25:19 | Chi [m1] | semmle.label | Chi [m1] |
| aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | semmle.label | pointerSetter output argument [m1] |
| aliasing.cpp:26:19:26:20 | Chi [m1] | semmle.label | Chi [m1] |
| aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | semmle.label | referenceSetter output argument [m1] |
| aliasing.cpp:29:11:29:12 | m1 | semmle.label | m1 |
| aliasing.cpp:30:11:30:12 | m1 | semmle.label | m1 |
| aliasing.cpp:37:13:37:22 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:38:11:38:12 | m1 | semmle.label | m1 |
| aliasing.cpp:42:11:42:20 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:43:13:43:14 | m1 | semmle.label | m1 |
| aliasing.cpp:60:3:60:22 | Chi [m1] | semmle.label | Chi [m1] |
| aliasing.cpp:60:3:60:22 | Store | semmle.label | Store |
| aliasing.cpp:60:11:60:20 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:61:13:61:14 | Store [m1] | semmle.label | Store [m1] |
| aliasing.cpp:62:14:62:15 | m1 | semmle.label | m1 |
| aliasing.cpp:79:11:79:20 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:80:12:80:13 | m1 | semmle.label | m1 |
| aliasing.cpp:86:10:86:19 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:87:12:87:13 | m1 | semmle.label | m1 |
| aliasing.cpp:92:12:92:21 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
| 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 |
| by_reference.cpp:88:3:88:24 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:88:3:88:24 | Store | semmle.label | Store |
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:102:21:102:39 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
| by_reference.cpp:106:21:106:41 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
| by_reference.cpp:110:27:110:27 | a | semmle.label | a |
| by_reference.cpp:114:29:114:29 | a | semmle.label | a |
| by_reference.cpp:122:21:122:38 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
| by_reference.cpp:126:21:126:40 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
| by_reference.cpp:130:27:130:27 | a | semmle.label | a |
| by_reference.cpp:134:29:134:29 | a | semmle.label | a |
| 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] |
| simple.cpp:67:13:67:13 | i | semmle.label | i |
| 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: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 |
#select
| A.cpp:154:10:154:13 | (void *)... | A.cpp:142:14:142:20 | new | A.cpp:154:10:154:13 | (void *)... | (void *)... flows from $@ | A.cpp:142:14:142:20 | new | new |
| A.cpp:154:13:154:13 | c | A.cpp:142:14:142:20 | new | A.cpp:154:13:154:13 | c | c flows from $@ | A.cpp:142:14:142:20 | new | new |
| aliasing.cpp:29:11:29:12 | m1 | aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:29:11:29:12 | m1 | m1 flows from $@ | aliasing.cpp:9:11:9:20 | call to user_input | call to user_input |
| aliasing.cpp:30:11:30:12 | m1 | aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:30:11:30:12 | m1 | m1 flows from $@ | aliasing.cpp:13:10:13:19 | call to user_input | call to user_input |
| aliasing.cpp:38:11:38:12 | m1 | aliasing.cpp:37:13:37:22 | call to user_input | aliasing.cpp:38:11:38:12 | m1 | m1 flows from $@ | aliasing.cpp:37:13:37:22 | call to user_input | call to user_input |
| aliasing.cpp:43:13:43:14 | m1 | aliasing.cpp:42:11:42:20 | call to user_input | aliasing.cpp:43:13:43:14 | m1 | m1 flows from $@ | aliasing.cpp:42:11:42:20 | call to user_input | call to user_input |
| aliasing.cpp:62:14:62:15 | m1 | aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:62:14:62:15 | m1 | m1 flows from $@ | aliasing.cpp:60:11:60:20 | call to user_input | call to user_input |
| aliasing.cpp:80:12:80:13 | m1 | aliasing.cpp:79:11:79:20 | call to user_input | aliasing.cpp:80:12:80:13 | m1 | m1 flows from $@ | aliasing.cpp:79:11:79:20 | call to user_input | call to user_input |
| aliasing.cpp:87:12:87:13 | m1 | aliasing.cpp:86:10:86:19 | call to user_input | aliasing.cpp:87:12:87:13 | m1 | m1 flows from $@ | aliasing.cpp:86:10:86:19 | call to user_input | call to user_input |
| aliasing.cpp:93:12:93:13 | m1 | aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 | m1 flows from $@ | aliasing.cpp:92:12:92:21 | call to user_input | call to user_input |
| by_reference.cpp:110:27:110:27 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:110:27:110:27 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:114:29:114:29 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:114:29:114:29 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:130:27:130:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:130:27:130:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| simple.cpp:67:13:67:13 | i | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:67:13:67:13 | i | i flows from $@ | simple.cpp:65:11:65:20 | call to user_input | call to user_input |
| struct_init.c:22:11:22:11 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:22:11:22:11 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |
| struct_init.c:31:23:31:23 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:31:23:31:23 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input |

View File

@@ -1,17 +1,13 @@
/**
* @kind path-problem
* @kind problem
*/
import TestUtilities.InlineExpectationsTest
import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl
import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon
import semmle.code.cpp.ir.IR
import DataFlow::PathGraph
import DataFlow
import cpp
class Conf extends DataFlow::Configuration {
class Conf extends Configuration {
Conf() { this = "FieldFlowConf" }
override predicate isSource(Node src) {
@@ -41,6 +37,28 @@ class Conf extends DataFlow::Configuration {
}
}
from DataFlow::PathNode src, DataFlow::PathNode sink, Conf conf
where conf.hasFlowPath(src, sink)
select sink, src, sink, sink + " flows from $@", src, src.toString()
class IRFieldFlowTest extends InlineExpectationsTest {
IRFieldFlowTest() { this = "IRFieldFlowTest" }
override string getARelevantTag() { result = "ir" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Node source, Node sink, Conf conf, int n |
tag = "ir" and
conf.hasFlow(source, sink) and
n = strictcount(Node otherSource | conf.hasFlow(otherSource, sink)) and
(
n = 1 and value = ""
or
// If there is more than one source for this sink
// we specify the source location explicitly.
n > 1 and
value =
source.getLocation().getStartLine().toString() + ":" +
source.getLocation().getStartColumn()
) and
location = sink.getLocation() and
element = sink.toString()
)
}
}

View File

@@ -20,31 +20,31 @@ namespace qualifiers {
void assignToGetter(Outer outer) {
outer.getInner()->a = user_input();
sink(outer.inner->a); // flow [NOT DETECTED by IR]
sink(outer.inner->a); // $ast $f-:ir
}
void getterArgument1(Outer outer) {
outer.getInner()->setA(user_input());
sink(outer.inner->a); // flow [NOT DETECTED by IR]
sink(outer.inner->a); // $ast $f-:ir
}
void getterArgument2(Outer outer) {
pointerSetA(outer.getInner(), user_input());
sink(outer.inner->a); // flow [NOT DETECTED by IR]
sink(outer.inner->a); // $ast $f-:ir
}
void getterArgument2Ref(Outer outer) {
referenceSetA(*outer.getInner(), user_input());
sink(outer.inner->a); // flow [NOT DETECTED by IR]
sink(outer.inner->a); // $ast $f-:ir
}
void assignToGetterStar(Outer outer) {
(*outer.getInner()).a = user_input();
sink(outer.inner->a); // flow [NOT DETECTED by IR]
sink(outer.inner->a); // $ast $f-:ir
}
void assignToGetterAmp(Outer outer) {
(&outer)->getInner()->a = user_input();
sink(outer.inner->a); // flow [NOT DETECTED by IR]
sink(outer.inner->a); // $ast $f-:ir
}
}

View File

@@ -25,8 +25,8 @@ public:
void bar(Foo &f)
{
sink(f.a()); // flow (through `f.setA` and `h.setA`)
sink(f.b()); // flow (through `g.setB` and `h.setB`)
sink(f.a()); //$ast=39:12 $ast=41:12 $f-:ir
sink(f.b()); //$ast=40:12 $ast=42:12 $f-:ir
}
void foo()
@@ -64,7 +64,7 @@ void single_field_test()
A a;
a.i = user_input();
A a2 = a;
sink(a2.i);
sink(a2.i); //$ast,ir
}
struct C {
@@ -81,7 +81,7 @@ struct C2
void m() {
f2.f1 = user_input();
sink(getf2f1()); // flow
sink(getf2f1()); //$ast $f-:ir
}
};

View File

@@ -12,14 +12,14 @@ struct Outer {
};
void absink(struct AB *ab) {
sink(ab->a); // flow (three sources)
sink(ab->a); //$ast=20:20 $ast=27:7 $ast=40:20 $f-:ir
sink(ab->b); // no flow
}
int struct_init(void) {
struct AB ab = { user_input(), 0 };
sink(ab.a); // flow
sink(ab.a); //$ast,ir
sink(ab.b); // no flow
absink(&ab);
@@ -28,9 +28,9 @@ int struct_init(void) {
&ab,
};
sink(outer.nestedAB.a); // flow
sink(outer.nestedAB.a); //$ast,ir
sink(outer.nestedAB.b); // no flow
sink(outer.pointerAB->a); // flow
sink(outer.pointerAB->a); //$ast $f-:ir
sink(outer.pointerAB->b); // no flow
absink(&outer.nestedAB);

View File

@@ -591,3 +591,13 @@
| taint.cpp:463:6:463:6 | 0 | taint.cpp:471:7:471:7 | y | |
| taint.cpp:468:7:468:7 | ref arg x | taint.cpp:470:7:470:7 | x | |
| taint.cpp:468:10:468:10 | ref arg y | taint.cpp:471:7:471:7 | y | |
| taint.cpp:480:26:480:32 | source1 | taint.cpp:483:28:483:34 | source1 | |
| taint.cpp:481:15:481:21 | 0 | taint.cpp:483:12:483:15 | line | |
| taint.cpp:481:15:481:21 | 0 | taint.cpp:485:7:485:10 | line | |
| taint.cpp:482:9:482:9 | n | taint.cpp:483:19:483:19 | n | |
| taint.cpp:483:11:483:15 | ref arg & ... | taint.cpp:483:12:483:15 | line [inner post update] | |
| taint.cpp:483:11:483:15 | ref arg & ... | taint.cpp:485:7:485:10 | line | |
| taint.cpp:483:12:483:15 | line | taint.cpp:483:11:483:15 | & ... | |
| taint.cpp:483:18:483:19 | ref arg & ... | taint.cpp:483:19:483:19 | n [inner post update] | |
| taint.cpp:483:19:483:19 | n | taint.cpp:483:18:483:19 | & ... | |
| taint.cpp:483:28:483:34 | source1 | taint.cpp:483:11:483:15 | ref arg & ... | TAINT |

View File

@@ -470,3 +470,17 @@ void test_swop() {
sink(x); // clean [FALSE POSITIVE]
sink(y); // tainted
}
// --- getdelim ---
struct FILE;
int getdelim(char ** lineptr, size_t * n, int delimiter, FILE *stream);
void test_getdelim(FILE* source1) {
char* line = nullptr;
size_t n;
getdelim(&line, &n, '\n', source1);
sink(line);
}

View File

@@ -67,3 +67,4 @@
| taint.cpp:465:7:465:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:471:7:471:7 | y | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |

View File

@@ -28,3 +28,4 @@
| taint.cpp:430:9:430:14 | member | taint.cpp:428:13:428:18 | call to source |
| taint.cpp:465:7:465:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |

View File

@@ -1,41 +1,31 @@
| ODASA-5186.cpp:4:8:4:8 | operator= | operator= | | | ODASA-5186.cpp:4:8:4:8 | declaration |
| ODASA-5186.cpp:4:8:4:8 | operator= | operator= | | | ODASA-5186.cpp:4:8:4:8 | declaration |
| ODASA-5186.cpp:5:8:5:8 | operator== | operator== | | | ODASA-5186.cpp:5:8:5:8 | declaration |
| ODASA-5186.cpp:5:8:5:8 | operator== | operator== | | | ODASA-5186.cpp:5:8:5:8 | definition |
| ODASA-5186.cpp:5:8:5:17 | operator== | operator== | | | ODASA-5186.cpp:5:8:5:17 | declaration |
| ODASA-5186.cpp:5:8:5:17 | operator== | operator== | | | ODASA-5186.cpp:5:8:5:17 | definition |
| ODASA-5186.cpp:8:6:8:9 | test | test | isTopLevel | TopLevelFunction | ODASA-5186.cpp:8:6:8:9 | declaration |
| ODASA-5186.cpp:8:6:8:9 | test | test | isTopLevel | TopLevelFunction | ODASA-5186.cpp:8:6:8:9 | definition |
| ODASA-5186.hpp:2:8:2:8 | operator= | operator= | | | ODASA-5186.hpp:2:8:2:8 | declaration |
| ODASA-5186.hpp:2:8:2:8 | operator= | operator= | | | ODASA-5186.hpp:2:8:2:8 | declaration |
| ODASA-5186.hpp:4:18:4:27 | operator!= | operator!= | isTopLevel | TopLevelFunction | ODASA-5186.hpp:4:18:4:27 | declaration |
| ODASA-5186.hpp:4:18:4:27 | operator!= | operator!= | isTopLevel | TopLevelFunction | ODASA-5186.hpp:4:18:4:27 | declaration |
| ODASA-5186.hpp:4:18:4:27 | operator!= | operator!= | isTopLevel | TopLevelFunction | ODASA-5186.hpp:4:18:4:27 | definition |
| ODASA-5186.hpp:4:18:4:27 | operator!= | operator!= | isTopLevel | TopLevelFunction | ODASA-5186.hpp:4:18:4:27 | definition |
| functions.cpp:1:6:1:6 | f | f | isTopLevel | TopLevelFunction | functions.cpp:1:6:1:6 | declaration |
| functions.cpp:1:6:1:6 | f | f | isTopLevel | TopLevelFunction | functions.cpp:1:6:1:6 | definition |
| functions.cpp:7:8:7:8 | operator= | operator= | | | functions.cpp:7:8:7:8 | declaration |
| functions.cpp:7:8:7:8 | operator= | operator= | | | functions.cpp:7:8:7:8 | declaration |
| functions.cpp:8:7:8:8 | af | af | | | functions.cpp:8:7:8:8 | declaration |
| functions.cpp:8:7:8:8 | af | af | | | functions.cpp:8:7:8:8 | definition |
| functions.cpp:11:7:11:8 | ag | ag | | | functions.cpp:11:7:11:8 | declaration |
| functions.cpp:14:6:14:6 | g | g | isTopLevel | TopLevelFunction | functions.cpp:5:6:5:6 | declaration |
| functions.cpp:14:6:14:6 | g | g | isTopLevel | TopLevelFunction | functions.cpp:14:6:14:6 | declaration |
| functions.cpp:14:6:14:6 | g | g | isTopLevel | TopLevelFunction | functions.cpp:14:6:14:6 | definition |
| functions.cpp:19:7:19:7 | operator= | operator= | | | functions.cpp:19:7:19:7 | declaration |
| functions.cpp:19:7:19:7 | operator= | operator= | | | functions.cpp:19:7:19:7 | declaration |
| functions.cpp:23:7:23:7 | Table | Table | | | functions.cpp:23:7:23:7 | declaration |
| functions.cpp:23:7:23:7 | operator= | operator= | | | functions.cpp:23:7:23:7 | declaration |
| functions.cpp:27:3:27:7 | Table | Table | | | functions.cpp:27:3:27:7 | declaration |
| functions.cpp:27:3:27:7 | Table | Table | | | functions.cpp:27:3:27:7 | definition |
| functions.cpp:28:3:28:8 | ~Table | ~Table | | | functions.cpp:28:3:28:8 | declaration |
| functions.cpp:28:3:28:8 | ~Table | ~Table | | | functions.cpp:28:3:28:8 | definition |
| functions.cpp:29:9:29:14 | lookup | lookup | | | functions.cpp:29:9:29:14 | declaration |
| functions.cpp:30:8:30:13 | insert | insert | | | functions.cpp:30:8:30:13 | declaration |
| functions.cpp:33:7:33:7 | operator= | operator= | | | functions.cpp:33:7:33:7 | declaration |
| functions.cpp:33:7:33:7 | operator= | operator= | | | functions.cpp:33:7:33:7 | definition |
| functions.cpp:36:2:36:8 | MyClass | MyClass | | | functions.cpp:36:2:36:8 | declaration |
| functions.cpp:37:2:37:8 | MyClass | MyClass | | | functions.cpp:37:2:37:8 | declaration |
| functions.cpp:38:2:38:8 | MyClass | MyClass | | | functions.cpp:38:2:38:8 | declaration |
| functions.cpp:39:2:39:8 | MyClass | MyClass | | | functions.cpp:39:2:39:8 | declaration |
| functions.cpp:40:2:40:13 | operator int | operator int | | | functions.cpp:40:2:40:13 | declaration |
| ODASA-5186.cpp:4:8:4:8 | operator= | operator= | MyClass<int> && p#0 | declaration:ODASA-5186.cpp:4:8:4:8 |
| ODASA-5186.cpp:4:8:4:8 | operator= | operator= | const MyClass<int> & p#0 | declaration:ODASA-5186.cpp:4:8:4:8 |
| ODASA-5186.cpp:5:8:5:8 | operator== | operator== | const MyClass<int> & other | declaration:ODASA-5186.cpp:5:8:5:8, definition:ODASA-5186.cpp:5:8:5:8 |
| ODASA-5186.cpp:5:8:5:17 | operator== | operator== | const MyClass<T> & other | declaration:ODASA-5186.cpp:5:8:5:17, definition:ODASA-5186.cpp:5:8:5:17 |
| ODASA-5186.cpp:8:6:8:9 | test | test | | TopLevelFunction, declaration:ODASA-5186.cpp:8:6:8:9, definition:ODASA-5186.cpp:8:6:8:9, isTopLevel |
| ODASA-5186.hpp:2:8:2:8 | operator= | operator= | NEQ_helper<MyClass<int>> && p#0 | declaration:ODASA-5186.hpp:2:8:2:8 |
| ODASA-5186.hpp:2:8:2:8 | operator= | operator= | const NEQ_helper<MyClass<int>> & p#0 | declaration:ODASA-5186.hpp:2:8:2:8 |
| ODASA-5186.hpp:4:18:4:27 | operator!= | operator!= | const MyClass<int> & x, const MyClass<int> & y | TopLevelFunction, declaration:ODASA-5186.hpp:4:18:4:27, definition:ODASA-5186.hpp:4:18:4:27, isTopLevel |
| ODASA-5186.hpp:4:18:4:27 | operator!= | operator!= | const T & x, const T & y | TopLevelFunction, declaration:ODASA-5186.hpp:4:18:4:27, definition:ODASA-5186.hpp:4:18:4:27, isTopLevel |
| functions.cpp:1:6:1:6 | f | f | int a, int b | TopLevelFunction, declaration:functions.cpp:1:6:1:6, definition:functions.cpp:1:6:1:6, isTopLevel |
| functions.cpp:7:8:7:8 | operator= | operator= | A && p#0 | declaration:functions.cpp:7:8:7:8 |
| functions.cpp:7:8:7:8 | operator= | operator= | const A & p#0 | declaration:functions.cpp:7:8:7:8 |
| functions.cpp:8:7:8:8 | af | af | | declaration:functions.cpp:8:7:8:8, definition:functions.cpp:8:7:8:8 |
| functions.cpp:11:7:11:8 | ag | ag | | declaration:functions.cpp:11:7:11:8 |
| functions.cpp:14:6:14:6 | g | g | | TopLevelFunction, declaration:functions.cpp:14:6:14:6, declaration:functions.cpp:5:6:5:6, definition:functions.cpp:14:6:14:6, isTopLevel |
| functions.cpp:19:7:19:7 | operator= | operator= | Name && p#0 | declaration:functions.cpp:19:7:19:7 |
| functions.cpp:19:7:19:7 | operator= | operator= | const Name & p#0 | declaration:functions.cpp:19:7:19:7 |
| functions.cpp:23:7:23:7 | Table | Table | const Table & p#0 | declaration:functions.cpp:23:7:23:7 |
| functions.cpp:23:7:23:7 | operator= | operator= | const Table & p#0 | declaration:functions.cpp:23:7:23:7 |
| functions.cpp:27:3:27:7 | Table | Table | int s | declaration:functions.cpp:27:3:27:7, definition:functions.cpp:27:3:27:7 |
| functions.cpp:28:3:28:8 | ~Table | ~Table | | declaration:functions.cpp:28:3:28:8, definition:functions.cpp:28:3:28:8 |
| functions.cpp:29:9:29:14 | lookup | lookup | const char * p#0 | declaration:functions.cpp:29:9:29:14 |
| functions.cpp:30:8:30:13 | insert | insert | Name * p#0 | declaration:functions.cpp:30:8:30:13 |
| functions.cpp:33:7:33:7 | operator= | operator= | const MyClass & p#0 | declaration:functions.cpp:33:7:33:7, definition:functions.cpp:33:7:33:7 |
| functions.cpp:36:2:36:8 | MyClass | MyClass | | declaration:functions.cpp:36:2:36:8 |
| functions.cpp:37:2:37:8 | MyClass | MyClass | int from | declaration:functions.cpp:37:2:37:8 |
| functions.cpp:38:2:38:8 | MyClass | MyClass | const MyClass & from | declaration:functions.cpp:38:2:38:8 |
| functions.cpp:39:2:39:8 | MyClass | MyClass | MyClass && from | declaration:functions.cpp:39:2:39:8 |
| functions.cpp:40:2:40:13 | operator int | operator int | | declaration:functions.cpp:40:2:40:13 |
| functions.cpp:43:6:43:6 | h | h | int x | TopLevelFunction, declaration:functions.cpp:43:6:43:6, declaration:functions.cpp:44:6:44:6, isTopLevel |
| functions.cpp:44:6:44:6 | h | h | int x | TopLevelFunction, declaration:functions.cpp:43:6:43:6, declaration:functions.cpp:44:6:44:6, isTopLevel |

View File

@@ -4,13 +4,18 @@
import cpp
from Function f, string top1, string top2, Location loc, string loctype
where
(if f.isTopLevel() then top1 = "isTopLevel" else top1 = "") and
(if f instanceof TopLevelFunction then top2 = "TopLevelFunction" else top2 = "") and
(
loc = f.getADeclarationLocation() and loctype = "declaration"
or
loc = f.getDefinitionLocation() and loctype = "definition"
)
select f, f.getName(), top1, top2, loc.toString(), loctype
string describe(Function f) {
f.isTopLevel() and
result = "isTopLevel"
or
f instanceof TopLevelFunction and
result = "TopLevelFunction"
or
result = "declaration:" + f.getADeclarationLocation()
or
result = "definition:" + f.getDefinitionLocation()
}
from Function f
where exists(f.getLocation())
select f, f.getName(), f.getParameterString(), concat(describe(f), ", ")

View File

@@ -39,3 +39,6 @@ public:
MyClass(MyClass &&from);
operator int();
};
void h(int x);
void h(int y);

View File

@@ -1,7 +1,6 @@
missingOperand
unexpectedOperand
duplicateOperand
| ssa.cpp:301:27:301:30 | ReturnIndirection: argv | Instruction has 2 operands with tag 'SideEffect' in function '$@'. | ssa.cpp:301:5:301:8 | IR: main | int main(int, char**) |
missingPhiOperand
missingOperandType
duplicateChiOperand

View File

@@ -1480,7 +1480,7 @@ ssa.cpp:
# 304| r304_5(char) = Load : &:r304_4, ~m303_8
# 304| r304_6(int) = Convert : r304_5
# 304| m304_7(int) = Store : &:r304_1, r304_6
# 301| v301_12(void) = ReturnIndirection[argv] : &:r301_10, ~m303_11, m303_11
# 301| v301_12(void) = ReturnIndirection[argv] : &:r301_10, m303_11
# 301| r301_13(glval<int>) = VariableAddress[#return] :
# 301| v301_14(void) = ReturnValue : &:r301_13, m304_7
# 301| v301_15(void) = AliasedUse : ~m303_8

View File

@@ -1,4 +1,13 @@
edges
| field_conflation.c:12:22:12:27 | call to getenv | field_conflation.c:13:10:13:25 | Chi |
| field_conflation.c:12:22:12:34 | (const char *)... | field_conflation.c:13:10:13:25 | Chi |
| field_conflation.c:13:10:13:25 | Chi | field_conflation.c:19:15:19:17 | taint_array output argument |
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:10:20:13 | (unsigned long)... |
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:13:20:13 | x |
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:13:20:13 | x |
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:13:20:13 | x |
| field_conflation.c:20:13:20:13 | x | field_conflation.c:20:10:20:13 | (unsigned long)... |
| field_conflation.c:20:13:20:13 | x | field_conflation.c:20:13:20:13 | x |
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | (size_t)... |
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | (size_t)... |
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted |
@@ -60,6 +69,15 @@ edges
| 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 |
nodes
| field_conflation.c:12:22:12:27 | call to getenv | semmle.label | call to getenv |
| field_conflation.c:12:22:12:34 | (const char *)... | semmle.label | (const char *)... |
| field_conflation.c:13:10:13:25 | Chi | semmle.label | Chi |
| field_conflation.c:19:15:19:17 | taint_array output argument | semmle.label | taint_array output argument |
| field_conflation.c:20:10:20:13 | (unsigned long)... | semmle.label | (unsigned long)... |
| field_conflation.c:20:10:20:13 | (unsigned long)... | semmle.label | (unsigned long)... |
| field_conflation.c:20:13:20:13 | x | semmle.label | x |
| field_conflation.c:20:13:20:13 | x | semmle.label | x |
| field_conflation.c:20:13:20:13 | x | semmle.label | x |
| test.cpp:39:21:39:24 | argv | semmle.label | argv |
| test.cpp:39:21:39:24 | argv | semmle.label | argv |
| test.cpp:42:38:42:44 | (size_t)... | semmle.label | (size_t)... |
@@ -123,6 +141,7 @@ nodes
| test.cpp:235:11:235:20 | (size_t)... | semmle.label | (size_t)... |
| test.cpp:237:10:237:19 | (size_t)... | semmle.label | (size_t)... |
#select
| field_conflation.c:20:3:20:8 | call to malloc | field_conflation.c:12:22:12:27 | call to getenv | field_conflation.c:20:13:20:13 | x | This allocation size is derived from $@ and might overflow | field_conflation.c:12:22:12:27 | call to getenv | user input (getenv) |
| test.cpp:42:31:42:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:63 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
| test.cpp:45:31:45:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:45:38:45:63 | ... + ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |

View File

@@ -0,0 +1,21 @@
int atoi(const char *nptr);
void *malloc(unsigned long size);
char *getenv(const char *name);
void *memcpy(void *dst, void *src, unsigned long size);
struct ContainsArray {
int arr[16];
int x;
};
void taint_array(struct ContainsArray *ca, int offset) {
int tainted = atoi(getenv("VAR"));
memcpy(ca->arr + offset, &tainted, sizeof(int));
}
void test_conflated_fields3(int arbitrary) {
struct ContainsArray ca;
ca.x = 4;
taint_array(&ca, arbitrary);
malloc(ca.x); // not tainted [FALSE POSITIVE]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Add union types for casts and accesses
compatibility: full

View File

@@ -1,7 +1,7 @@
/**
* @name Invalid format string
* @description Using a format string with an incorrect format causes a 'System.FormatException'.
* @kind problem
* @kind path-problem
* @problem.severity error
* @precision high
* @id cs/invalid-format-string
@@ -11,7 +11,8 @@
import csharp
import semmle.code.csharp.frameworks.Format
import FormatFlow
from FormatCall s, InvalidFormatString src
where src = s.getAFormatSource()
select src, "Invalid format string used in $@ formatting call.", s, "this"
from FormatCall s, InvalidFormatString src, PathNode source, PathNode sink
where hasFlowPath(src, source, s, sink)
select src, source, sink, "Invalid format string used in $@ formatting call.", s, "this"

View File

@@ -1,7 +1,7 @@
/**
* @name Missing format argument
* @description Supplying too few arguments to a format string causes a 'System.FormatException'.
* @kind problem
* @kind path-problem
* @problem.severity error
* @precision high
* @id cs/format-argument-missing
@@ -11,11 +11,14 @@
import csharp
import semmle.code.csharp.frameworks.Format
import FormatFlow
from FormatCall format, ValidFormatString src, int used, int supplied
from
FormatCall format, ValidFormatString src, int used, int supplied, PathNode source, PathNode sink
where
src = format.getAFormatSource() and
hasFlowPath(src, source, format, sink) and
used = src.getAnInsert() and
supplied = format.getSuppliedArguments() and
used >= supplied
select format, "Argument '{" + used + "}' has not been supplied to $@ format string.", src, "this"
select format, source, sink, "Argument '{" + used + "}' has not been supplied to $@ format string.",
src, "this"

View File

@@ -1,7 +1,7 @@
/**
* @name Unused format argument
* @description Supplying more arguments than are required for a format string may indicate an error in the format string.
* @kind problem
* @kind path-problem
* @problem.severity warning
* @precision high
* @id cs/format-argument-unused
@@ -11,11 +11,12 @@
import csharp
import semmle.code.csharp.frameworks.Format
import FormatFlow
from FormatCall format, int unused, ValidFormatString src
from FormatCall format, int unused, ValidFormatString src, PathNode source, PathNode sink
where
src = format.getAFormatSource() and
hasFlowPath(src, source, format, sink) and
unused = format.getAnUnusedArgument(src) and
not src.getValue() = ""
select format, "The $@ ignores $@.", src, "format string", format.getSuppliedExpr(unused),
"this supplied value"
select format, source, sink, "The $@ ignores $@.", src, "format string",
format.getSuppliedExpr(unused), "this supplied value"

View File

@@ -250,7 +250,7 @@ private module Gvn {
private class LeafType extends Type {
LeafType() {
not exists(this.getAChild()) and
not this instanceof Unification::GenericType and
not this instanceof MethodTypeParameter and
not this instanceof DynamicType
}
@@ -267,7 +267,9 @@ private module Gvn {
gvnConstructedCons(_, _, _, head, tail)
}
private ConstructedGvnTypeList gvnConstructed(Type t, Unification::CompoundTypeKind k, int i) {
private ConstructedGvnTypeList gvnConstructed(
Unification::GenericType t, Unification::CompoundTypeKind k, int i
) {
result = TConstructedGvnTypeNil(k) and
i = -1 and
k = Unification::getTypeKind(t)
@@ -278,14 +280,17 @@ private module Gvn {
}
pragma[noinline]
private GvnType gvnTypeChild(Type t, int i) { result = getGlobalValueNumber(t.getChild(i)) }
private GvnType gvnTypeArgument(Unification::GenericType t, int i) {
result = getGlobalValueNumber(t.getArgument(i))
}
pragma[noinline]
private predicate gvnConstructedCons(
Type t, Unification::CompoundTypeKind k, int i, GvnType head, ConstructedGvnTypeList tail
Unification::GenericType t, Unification::CompoundTypeKind k, int i, GvnType head,
ConstructedGvnTypeList tail
) {
tail = gvnConstructed(t, k, i - 1) and
head = gvnTypeChild(t, i)
head = gvnTypeArgument(t, i)
}
/** Gets the global value number for a given type. */
@@ -319,6 +324,8 @@ private module Gvn {
}
private class ConstructedGvnTypeList extends TConstructedGvnTypeList {
Unification::CompoundTypeKind getKind() { this = gvnConstructed(_, result, _) }
private int length() {
this = TConstructedGvnTypeNil(_) and result = -1
or
@@ -338,17 +345,47 @@ private module Gvn {
)
}
/**
* Gets a textual representation of this constructed type, restricted
* to the prefix `t` of the underlying source declaration type.
*
* The `toString()` calculation needs to be split up into prefixes, in
* order to apply the type arguments correctly. For example, a source
* declaration type `A<>.B.C<,>` applied to types `int, string, bool`
* needs to be printed as `A<int>.B.C<string,bool>`.
*/
language[monotonicAggregates]
private string toStringConstructed(Unification::GenericType t) {
t = this.getKind().getConstructedSourceDeclaration().getGenericDeclaringType*() and
exists(int offset, int children, string name, string nameArgs |
offset = t.getNumberOfDeclaringArguments() and
children = t.getNumberOfArgumentsSelf() and
name = Unification::getNameNested(t) and
if children = 0
then nameArgs = name
else
exists(string offsetArgs |
offsetArgs =
concat(int i |
i in [offset .. offset + children - 1]
|
this.getArg(i).toString(), "," order by i
) and
nameArgs = name.prefix(name.length() - children - 1) + "<" + offsetArgs + ">"
)
|
offset = 0 and result = nameArgs
or
result = this.toStringConstructed(t.getGenericDeclaringType()) + "." + nameArgs
)
}
language[monotonicAggregates]
string toString() {
exists(Unification::CompoundTypeKind k, string args |
this = gvnConstructed(_, k, _) and
args =
concat(int i |
i in [0 .. k.getNumberOfTypeParameters() - 1]
|
this.getArg(i).toString(), "," order by i
) and
result = k.toString(args)
exists(Unification::CompoundTypeKind k | k = this.getKind() |
result = k.toStringBuiltin(this.getArg(0).toString())
or
result = this.toStringConstructed(k.getConstructedSourceDeclaration())
)
}

View File

@@ -10,9 +10,75 @@ private import Caching
* equal modulo identity conversions and type parameters.
*/
module Gvn {
/**
* Gets the name of type `t`, including the enclosing type of `t` as a qualifier,
* but only if the enclosing type is not a `GenericType`.
*/
string getNameNested(Type t) {
if not t instanceof NestedType or t.(NestedType).getDeclaringType() instanceof GenericType
then result = t.getName()
else result = getNameNested(t.(NestedType).getDeclaringType()) + "." + t.getName()
}
/**
* A generic type. This is either a type with a type parameter, a type with
* a type argument, or a nested type with a generic enclosing type.
*
* In this class, type parameters and type arguments are collectively referred
* to as "arguments".
*/
class GenericType extends Type {
GenericType() {
exists(this.getChild(0))
or
this.(NestedType).getDeclaringType() instanceof GenericType
}
/** Gets the generic containing type, if any. */
GenericType getGenericDeclaringType() { result = this.(NestedType).getDeclaringType() }
/**
* Gets the number of arguments of the generic containing type, or 0 if there
* is no generic containing type.
*/
int getNumberOfDeclaringArguments() {
result = this.getGenericDeclaringType().getNumberOfArguments()
or
not exists(this.getGenericDeclaringType()) and result = 0
}
/** Gets the number of arguments of this type, not taking nested types into account. */
int getNumberOfArgumentsSelf() { result = count(int i | exists(this.getChild(i)) and i >= 0) }
/** Gets the number of arguments of this type, taking nested types into account. */
int getNumberOfArguments() {
result = this.getNumberOfDeclaringArguments() + this.getNumberOfArgumentsSelf()
}
/** Gets the `i`th argument of this type, taking nested types into account. */
Type getArgument(int i) {
result = this.getGenericDeclaringType().getArgument(i)
or
exists(int offset |
offset = this.getNumberOfDeclaringArguments() and
result = this.getChild(i - offset) and
i >= offset
)
}
/** Gets a textual representation of this type, taking nested types into account. */
string toStringNested() {
exists(string name | name = getNameNested(this) |
result = this.getGenericDeclaringType().toStringNested() + "." + name
or
not exists(this.getGenericDeclaringType()) and result = name
)
}
}
private class LeafType extends Type {
LeafType() {
not exists(this.getAChild()) and
not this instanceof GenericType and
not this instanceof TypeParameter and
not this instanceof DynamicType
}
@@ -28,14 +94,22 @@ module Gvn {
or
this = TArrayTypeKind(_, _) and result = 1
or
exists(UnboundGenericType ugt | this = TConstructedType(ugt) |
result = ugt.getNumberOfTypeParameters()
exists(GenericType t | this = TConstructedType(t.getSourceDeclaration()) |
result = t.getNumberOfArguments()
)
}
/** Gets a textual representation of this kind when applied to arguments `args`. */
/** Gets the source declaration type that this kind corresponds to, if any. */
GenericType getConstructedSourceDeclaration() { this = TConstructedType(result) }
/**
* Gets a textual representation of this kind when applied to arguments `args`.
*
* This predicate is restricted to built-in generics (pointers, nullables, and
* arrays).
*/
bindingset[args]
string toString(string args) {
string toStringBuiltin(string args) {
this = TPointerTypeKind() and result = args + "*"
or
this = TNullableTypeKind() and result = args + "?"
@@ -43,14 +117,14 @@ module Gvn {
exists(int rnk | this = TArrayTypeKind(_, rnk) |
result = args + "[" + concat(int i | i in [0 .. rnk - 2] | ",") + "]"
)
or
exists(UnboundGenericType ugt | this = TConstructedType(ugt) |
result = ugt.getNameWithoutBrackets() + "<" + args + ">"
)
}
/** Gets a textual representation of this kind. */
string toString() { result = toString("") }
string toString() {
result = this.toStringBuiltin("")
or
result = this.getConstructedSourceDeclaration().toStringNested()
}
/** Gets the location of this kind. */
Location getLocation() { result instanceof EmptyLocation }
@@ -64,11 +138,9 @@ module Gvn {
or
t = any(ArrayType at | result = TArrayTypeKind(at.getDimension(), at.getRank()))
or
result = TConstructedType(t.(ConstructedType).getUnboundGeneric())
result = TConstructedType(t.getSourceDeclaration())
or
result = TConstructedType(t.(TupleType).getUnderlyingType().getUnboundGeneric())
or
result = TConstructedType(t)
result = TConstructedType(t.(TupleType).getUnderlyingType().getSourceDeclaration())
}
/**
@@ -107,7 +179,7 @@ module Gvn {
override CompoundTypeKind getKind() { result = l.getKind() }
}
private ConstructedGvnTypeList gvnConstructed(Type t, CompoundTypeKind k, int i) {
private ConstructedGvnTypeList gvnConstructed(GenericType t, CompoundTypeKind k, int i) {
result = TConstructedGvnTypeNil(k) and
i = -1 and
k = getTypeKind(t)
@@ -118,14 +190,16 @@ module Gvn {
}
pragma[noinline]
private GvnType gvnTypeChild(Type t, int i) { result = getGlobalValueNumber(t.getChild(i)) }
private GvnType gvnTypeArgument(GenericType t, int i) {
result = getGlobalValueNumber(t.getArgument(i))
}
pragma[noinline]
private predicate gvnConstructedCons(
Type t, CompoundTypeKind k, int i, GvnType head, ConstructedGvnTypeList tail
GenericType t, CompoundTypeKind k, int i, GvnType head, ConstructedGvnTypeList tail
) {
tail = gvnConstructed(t, k, i - 1) and
head = gvnTypeChild(t, i)
head = gvnTypeArgument(t, i)
}
private class ConstructedGvnTypeList extends TConstructedGvnTypeList {
@@ -150,17 +224,47 @@ module Gvn {
)
}
/**
* Gets a textual representation of this constructed type, restricted
* to the prefix `t` of the underlying source declaration type.
*
* The `toString()` calculation needs to be split up into prefixes, in
* order to apply the type arguments correctly. For example, a source
* declaration type `A<>.B.C<,>` applied to types `int, string, bool`
* needs to be printed as `A<int>.B.C<string,bool>`.
*/
language[monotonicAggregates]
private string toStringConstructed(GenericType t) {
t = this.getKind().getConstructedSourceDeclaration().getGenericDeclaringType*() and
exists(int offset, int children, string name, string nameArgs |
offset = t.getNumberOfDeclaringArguments() and
children = t.getNumberOfArgumentsSelf() and
name = getNameNested(t) and
if children = 0
then nameArgs = name
else
exists(string offsetArgs |
offsetArgs =
concat(int i |
i in [offset .. offset + children - 1]
|
this.getArg(i).toString(), "," order by i
) and
nameArgs = name.prefix(name.length() - children - 1) + "<" + offsetArgs + ">"
)
|
offset = 0 and result = nameArgs
or
result = this.toStringConstructed(t.getGenericDeclaringType()) + "." + nameArgs
)
}
language[monotonicAggregates]
string toString() {
exists(CompoundTypeKind k, string args |
k = this.getKind() and
args =
concat(int i |
i in [0 .. k.getNumberOfTypeParameters() - 1]
|
this.getArg(i).toString(), "," order by i
) and
result = k.toString(args)
exists(CompoundTypeKind k | k = this.getKind() |
result = k.toStringBuiltin(this.getArg(0).toString())
or
result = this.toStringConstructed(k.getConstructedSourceDeclaration())
)
}
@@ -366,7 +470,12 @@ module Gvn {
TArrayTypeKind(int dim, int rnk) {
exists(ArrayType at | dim = at.getDimension() and rnk = at.getRank())
} or
TConstructedType(UnboundGenericType ugt) { exists(ugt.getATypeParameter()) }
TConstructedType(GenericType sourceDecl) {
sourceDecl = any(GenericType t).getSourceDeclaration() and
not sourceDecl instanceof PointerType and
not sourceDecl instanceof NullableType and
not sourceDecl instanceof ArrayType
}
cached
newtype TGvnType =

View File

@@ -173,7 +173,7 @@ class InvalidFormatString extends StringLiteral {
}
/** Provides a dataflow configuration for format strings. */
private module FormatFlow {
module FormatFlow {
private import semmle.code.csharp.dataflow.DataFlow
private class FormatConfiguration extends DataFlow2::Configuration {
@@ -186,12 +186,21 @@ private module FormatFlow {
}
}
predicate hasFlow(StringLiteral lit, Expr format) {
exists(DataFlow::Node n1, DataFlow::Node n2, FormatConfiguration conf |
n1.asExpr() = lit and n2.asExpr() = format
|
conf.hasFlow(n1, n2)
)
query predicate nodes = DataFlow2::PathGraph::nodes/3;
query predicate edges = DataFlow2::PathGraph::edges/2;
class PathNode = DataFlow2::PathNode;
/**
* Holds if there is flow from string literal `lit` to the format string in
* `call`. `litNode` and `formatNode` are the corresponding data-flow path
* nodes.
*/
predicate hasFlowPath(StringLiteral lit, PathNode litNode, FormatCall call, PathNode formatNode) {
litNode.getNode().asExpr() = lit and
formatNode.getNode().asExpr() = call.getFormatExpr() and
any(FormatConfiguration conf).hasFlowPath(litNode, formatNode)
}
}
@@ -218,10 +227,12 @@ class FormatCall extends MethodCall {
}
/**
* DEPRECATED: Use `FormatFlow::hasFlowPath()` instead.
*
* Gets a format string. Global data flow analysis is applied to retrieve all
* sources that can reach this method call.
*/
StringLiteral getAFormatSource() { FormatFlow::hasFlow(result, this.getFormatExpr()) }
deprecated StringLiteral getAFormatSource() { FormatFlow::hasFlowPath(result, _, this, _) }
/**
* Gets the number of supplied arguments (excluding the format string and format
@@ -245,7 +256,7 @@ class FormatCall extends MethodCall {
/** Gets a supplied argument that is not used in the format string `src`. */
int getAnUnusedArgument(ValidFormatString src) {
result = this.getASuppliedArgument() and
src = this.getAFormatSource() and
FormatFlow::hasFlowPath(src, _, this, _) and
not result = src.getAnInsert()
}
}

View File

@@ -221,7 +221,9 @@ PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
result = TPositionalArgumentOperand(argIndex)
}
class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
abstract class ChiOperandTag extends MemoryOperandTag { }
class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
final override string toString() { result = "ChiTotal" }
final override int getSortOrder() { result = 13 }
@@ -231,7 +233,7 @@ class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
class ChiPartialOperandTag extends MemoryOperandTag, TChiPartialOperand {
class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
final override string toString() { result = "ChiPartial" }
final override int getSortOrder() { result = 14 }

View File

@@ -14,12 +14,8 @@ private newtype TOperand =
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
useInstr.getOpcode().hasOperand(tag)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -27,6 +23,57 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/**
* Base class for all register operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class RegisterOperandBase extends TRegisterOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the register operand with the specified parameters.
*/
private RegisterOperandBase registerOperand(
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
) {
result = TRegisterOperand(useInstr, tag, defInstr)
}
/**
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
* will eventually use for this purpose.
*/
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
result = TNonPhiMemoryOperand(useInstr, tag)
}
/**
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class PhiOperandBase extends TPhiOperand {
abstract string toString();
}
/**
* Returns the Phi operand with the specified parameters.
*/
private PhiOperandBase phiOperand(
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
) {
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/
@@ -165,8 +212,8 @@ class Operand extends TOperand {
*/
class MemoryOperand extends Operand {
MemoryOperand() {
this = TNonPhiMemoryOperand(_, _, _, _) or
this = TPhiOperand(_, _, _, _)
this instanceof NonPhiMemoryOperandBase or
this instanceof PhiOperandBase
}
/**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
*/
class NonPhiOperand extends Operand {
Instruction useInstr;
Instruction defInstr;
OperandTag tag;
NonPhiOperand() {
this = TRegisterOperand(useInstr, tag, defInstr) or
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
this = registerOperand(useInstr, tag, _) or
this = nonPhiMemoryOperand(useInstr, tag)
}
final override Instruction getUse() { result = useInstr }
final override Instruction getAnyDef() { result = defInstr }
final override string getDumpLabel() { result = tag.getLabel() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
/**
* An operand that consumes a register (non-memory) result.
*/
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
override RegisterOperandTag tag;
Instruction defInstr;
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() { result = defInstr }
final override Overlap getDefinitionOverlap() {
// All register results overlap exactly with their uses.
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
}
}
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
override MemoryOperandTag tag;
Overlap overlap;
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
final override Overlap getDefinitionOverlap() { result = overlap }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() {
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
}
class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
*/
class AddressOperand extends RegisterOperand {
override AddressOperandTag tag;
override string toString() { result = "Address" }
}
/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/**
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
*/
class LoadOperand extends TypedOperand {
override LoadOperandTag tag;
override string toString() { result = "Load" }
}
/**
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
*/
class StoreValueOperand extends RegisterOperand {
override StoreValueOperandTag tag;
override string toString() { result = "StoreValue" }
}
/**
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
*/
class UnaryOperand extends RegisterOperand {
override UnaryOperandTag tag;
override string toString() { result = "Unary" }
}
/**
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
*/
class LeftOperand extends RegisterOperand {
override LeftOperandTag tag;
override string toString() { result = "Left" }
}
/**
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
*/
class RightOperand extends RegisterOperand {
override RightOperandTag tag;
override string toString() { result = "Right" }
}
/**
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
*/
class ConditionOperand extends RegisterOperand {
override ConditionOperandTag tag;
override string toString() { result = "Condition" }
}
/**
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
*/
class CallTargetOperand extends RegisterOperand {
override CallTargetOperandTag tag;
override string toString() { result = "CallTarget" }
}
/**
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
*/
class ThisArgumentOperand extends ArgumentOperand {
override ThisArgumentOperandTag tag;
override string toString() { result = "ThisArgument" }
}
/**
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
*/
class PositionalArgumentOperand extends ArgumentOperand {
override PositionalArgumentOperandTag tag;
int argIndex;
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
override string toString() { result = "Arg(" + argIndex + ")" }
/**
* Gets the zero-based index of the argument.
*/
final int getIndex() { result = argIndex }
final int getIndex() { result = tag.getArgIndex() }
}
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override string toString() { result = "SideEffect" }
}
/**
* An operand of a `PhiInstruction`.
*/
class PhiInputOperand extends MemoryOperand, TPhiOperand {
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
Overlap overlap;
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
override string toString() { result = "Phi" }
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
class ChiTotalOperand extends NonPhiMemoryOperand {
override ChiTotalOperandTag tag;
override string toString() { result = "ChiTotal" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
}
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
class ChiPartialOperand extends NonPhiMemoryOperand {
override ChiPartialOperandTag tag;
override string toString() { result = "ChiPartial" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
}

View File

@@ -14,12 +14,8 @@ private newtype TOperand =
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
useInstr.getOpcode().hasOperand(tag)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -27,6 +23,57 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/**
* Base class for all register operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class RegisterOperandBase extends TRegisterOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the register operand with the specified parameters.
*/
private RegisterOperandBase registerOperand(
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
) {
result = TRegisterOperand(useInstr, tag, defInstr)
}
/**
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
* will eventually use for this purpose.
*/
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
/** Gets a textual representation of this element. */
abstract string toString();
}
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
result = TNonPhiMemoryOperand(useInstr, tag)
}
/**
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
* eventually use for this purpose.
*/
private class PhiOperandBase extends TPhiOperand {
abstract string toString();
}
/**
* Returns the Phi operand with the specified parameters.
*/
private PhiOperandBase phiOperand(
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
) {
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/
@@ -165,8 +212,8 @@ class Operand extends TOperand {
*/
class MemoryOperand extends Operand {
MemoryOperand() {
this = TNonPhiMemoryOperand(_, _, _, _) or
this = TPhiOperand(_, _, _, _)
this instanceof NonPhiMemoryOperandBase or
this instanceof PhiOperandBase
}
/**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
*/
class NonPhiOperand extends Operand {
Instruction useInstr;
Instruction defInstr;
OperandTag tag;
NonPhiOperand() {
this = TRegisterOperand(useInstr, tag, defInstr) or
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
this = registerOperand(useInstr, tag, _) or
this = nonPhiMemoryOperand(useInstr, tag)
}
final override Instruction getUse() { result = useInstr }
final override Instruction getAnyDef() { result = defInstr }
final override string getDumpLabel() { result = tag.getLabel() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
/**
* An operand that consumes a register (non-memory) result.
*/
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
override RegisterOperandTag tag;
Instruction defInstr;
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() { result = defInstr }
final override Overlap getDefinitionOverlap() {
// All register results overlap exactly with their uses.
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
}
}
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
override MemoryOperandTag tag;
Overlap overlap;
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
final override Overlap getDefinitionOverlap() { result = overlap }
final override string toString() { result = tag.toString() }
final override Instruction getAnyDef() {
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
}
class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
*/
class AddressOperand extends RegisterOperand {
override AddressOperandTag tag;
override string toString() { result = "Address" }
}
/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
*/
class BufferSizeOperand extends RegisterOperand {
override BufferSizeOperandTag tag;
override string toString() { result = "BufferSize" }
}
/**
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
*/
class LoadOperand extends TypedOperand {
override LoadOperandTag tag;
override string toString() { result = "Load" }
}
/**
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
*/
class StoreValueOperand extends RegisterOperand {
override StoreValueOperandTag tag;
override string toString() { result = "StoreValue" }
}
/**
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
*/
class UnaryOperand extends RegisterOperand {
override UnaryOperandTag tag;
override string toString() { result = "Unary" }
}
/**
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
*/
class LeftOperand extends RegisterOperand {
override LeftOperandTag tag;
override string toString() { result = "Left" }
}
/**
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
*/
class RightOperand extends RegisterOperand {
override RightOperandTag tag;
override string toString() { result = "Right" }
}
/**
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
*/
class ConditionOperand extends RegisterOperand {
override ConditionOperandTag tag;
override string toString() { result = "Condition" }
}
/**
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
*/
class CallTargetOperand extends RegisterOperand {
override CallTargetOperandTag tag;
override string toString() { result = "CallTarget" }
}
/**
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
*/
class ThisArgumentOperand extends ArgumentOperand {
override ThisArgumentOperandTag tag;
override string toString() { result = "ThisArgument" }
}
/**
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
*/
class PositionalArgumentOperand extends ArgumentOperand {
override PositionalArgumentOperandTag tag;
int argIndex;
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
override string toString() { result = "Arg(" + argIndex + ")" }
/**
* Gets the zero-based index of the argument.
*/
final int getIndex() { result = argIndex }
final int getIndex() { result = tag.getArgIndex() }
}
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override string toString() { result = "SideEffect" }
}
/**
* An operand of a `PhiInstruction`.
*/
class PhiInputOperand extends MemoryOperand, TPhiOperand {
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
PhiInstruction useInstr;
Instruction defInstr;
IRBlock predecessorBlock;
Overlap overlap;
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
override string toString() { result = "Phi" }
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
class ChiTotalOperand extends NonPhiMemoryOperand {
override ChiTotalOperandTag tag;
override string toString() { result = "ChiTotal" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
}
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
class ChiPartialOperand extends NonPhiMemoryOperand {
override ChiPartialOperandTag tag;
override string toString() { result = "ChiPartial" }
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
}

View File

@@ -32,17 +32,17 @@ edges
| Types.cs:74:9:74:9 | access to local variable d : D | Types.cs:16:30:16:30 | this : D |
| Types.cs:77:22:77:22 | a : C | Types.cs:79:18:79:25 | SSA def(b) : C |
| Types.cs:79:18:79:25 | SSA def(b) : C | Types.cs:80:18:80:18 | access to local variable b |
| Types.cs:90:22:90:22 | e : E2 | Types.cs:92:26:92:26 | access to parameter e : E2 |
| Types.cs:92:13:92:16 | [post] this access [Field] : E2 | Types.cs:93:13:93:16 | this access [Field] : E2 |
| Types.cs:92:26:92:26 | access to parameter e : E2 | Types.cs:92:13:92:16 | [post] this access [Field] : E2 |
| Types.cs:93:13:93:16 | this access [Field] : E2 | Types.cs:113:34:113:34 | this [Field] : E2 |
| Types.cs:110:25:110:32 | object creation of type E2 : E2 | Types.cs:90:22:90:22 | e : E2 |
| Types.cs:113:34:113:34 | this [Field] : E2 | Types.cs:115:22:115:25 | this access [Field] : E2 |
| Types.cs:115:22:115:25 | this access [Field] : E2 | Types.cs:115:22:115:31 | access to field Field |
| Types.cs:90:22:90:22 | e : Types.E<D>.E2 | Types.cs:92:26:92:26 | access to parameter e : Types.E<D>.E2 |
| Types.cs:92:13:92:16 | [post] this access [Field] : Types.E<D>.E2 | Types.cs:93:13:93:16 | this access [Field] : Types.E<D>.E2 |
| Types.cs:92:26:92:26 | access to parameter e : Types.E<D>.E2 | Types.cs:92:13:92:16 | [post] this access [Field] : Types.E<D>.E2 |
| Types.cs:93:13:93:16 | this access [Field] : Types.E<D>.E2 | Types.cs:113:34:113:34 | this [Field] : Types.E<D>.E2 |
| Types.cs:110:25:110:32 | object creation of type E2 : Types.E<D>.E2 | Types.cs:90:22:90:22 | e : Types.E<D>.E2 |
| Types.cs:113:34:113:34 | this [Field] : Types.E<D>.E2 | Types.cs:115:22:115:25 | this access [Field] : Types.E<D>.E2 |
| Types.cs:115:22:115:25 | this access [Field] : Types.E<D>.E2 | Types.cs:115:22:115:31 | access to field Field |
| Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:122:30:122:30 | access to local variable a : A |
| Types.cs:121:26:121:33 | object creation of type E2 : E2 | Types.cs:123:30:123:31 | access to local variable e2 : E2 |
| Types.cs:121:26:121:33 | object creation of type E2 : Types.E<D>.E2 | Types.cs:123:30:123:31 | access to local variable e2 : Types.E<D>.E2 |
| Types.cs:122:30:122:30 | access to local variable a : A | Types.cs:122:22:122:31 | call to method Through |
| Types.cs:123:30:123:31 | access to local variable e2 : E2 | Types.cs:123:22:123:32 | call to method Through |
| Types.cs:123:30:123:31 | access to local variable e2 : Types.E<D>.E2 | Types.cs:123:22:123:32 | call to method Through |
nodes
| Types.cs:7:21:7:25 | this : D | semmle.label | this : D |
| Types.cs:7:32:7:35 | this access : D | semmle.label | this access : D |
@@ -86,20 +86,20 @@ nodes
| Types.cs:77:22:77:22 | a : C | semmle.label | a : C |
| Types.cs:79:18:79:25 | SSA def(b) : C | semmle.label | SSA def(b) : C |
| Types.cs:80:18:80:18 | access to local variable b | semmle.label | access to local variable b |
| Types.cs:90:22:90:22 | e : E2 | semmle.label | e : E2 |
| Types.cs:92:13:92:16 | [post] this access [Field] : E2 | semmle.label | [post] this access [Field] : E2 |
| Types.cs:92:26:92:26 | access to parameter e : E2 | semmle.label | access to parameter e : E2 |
| Types.cs:93:13:93:16 | this access [Field] : E2 | semmle.label | this access [Field] : E2 |
| Types.cs:110:25:110:32 | object creation of type E2 : E2 | semmle.label | object creation of type E2 : E2 |
| Types.cs:113:34:113:34 | this [Field] : E2 | semmle.label | this [Field] : E2 |
| Types.cs:115:22:115:25 | this access [Field] : E2 | semmle.label | this access [Field] : E2 |
| Types.cs:90:22:90:22 | e : Types.E<D>.E2 | semmle.label | e : Types.E<D>.E2 |
| Types.cs:92:13:92:16 | [post] this access [Field] : Types.E<D>.E2 | semmle.label | [post] this access [Field] : Types.E<D>.E2 |
| Types.cs:92:26:92:26 | access to parameter e : Types.E<D>.E2 | semmle.label | access to parameter e : Types.E<D>.E2 |
| Types.cs:93:13:93:16 | this access [Field] : Types.E<D>.E2 | semmle.label | this access [Field] : Types.E<D>.E2 |
| Types.cs:110:25:110:32 | object creation of type E2 : Types.E<D>.E2 | semmle.label | object creation of type E2 : Types.E<D>.E2 |
| Types.cs:113:34:113:34 | this [Field] : Types.E<D>.E2 | semmle.label | this [Field] : Types.E<D>.E2 |
| Types.cs:115:22:115:25 | this access [Field] : Types.E<D>.E2 | semmle.label | this access [Field] : Types.E<D>.E2 |
| Types.cs:115:22:115:31 | access to field Field | semmle.label | access to field Field |
| Types.cs:120:25:120:31 | object creation of type A : A | semmle.label | object creation of type A : A |
| Types.cs:121:26:121:33 | object creation of type E2 : E2 | semmle.label | object creation of type E2 : E2 |
| Types.cs:121:26:121:33 | object creation of type E2 : Types.E<D>.E2 | semmle.label | object creation of type E2 : Types.E<D>.E2 |
| Types.cs:122:22:122:31 | call to method Through | semmle.label | call to method Through |
| Types.cs:122:30:122:30 | access to local variable a : A | semmle.label | access to local variable a : A |
| Types.cs:123:22:123:32 | call to method Through | semmle.label | call to method Through |
| Types.cs:123:30:123:31 | access to local variable e2 : E2 | semmle.label | access to local variable e2 : E2 |
| Types.cs:123:30:123:31 | access to local variable e2 : Types.E<D>.E2 | semmle.label | access to local variable e2 : Types.E<D>.E2 |
#select
| Types.cs:23:12:23:18 | object creation of type C : C | Types.cs:50:18:50:18 | access to local variable c | Types.cs:50:18:50:18 | access to local variable c | $@ | Types.cs:50:18:50:18 | access to local variable c | access to local variable c |
| Types.cs:25:12:25:18 | object creation of type C : C | Types.cs:63:33:63:36 | (...) ... | Types.cs:63:33:63:36 | (...) ... | $@ | Types.cs:63:33:63:36 | (...) ... | (...) ... |
@@ -115,6 +115,6 @@ nodes
| Types.cs:39:12:39:18 | object creation of type D : D | Types.cs:69:52:69:52 | access to parameter x | Types.cs:69:52:69:52 | access to parameter x | $@ | Types.cs:69:52:69:52 | access to parameter x | access to parameter x |
| Types.cs:40:12:40:18 | object creation of type D : D | Types.cs:16:42:16:45 | this access | Types.cs:16:42:16:45 | this access | $@ | Types.cs:16:42:16:45 | this access | this access |
| Types.cs:43:20:43:23 | null : null | Types.cs:44:14:44:14 | access to local variable o | Types.cs:44:14:44:14 | access to local variable o | $@ | Types.cs:44:14:44:14 | access to local variable o | access to local variable o |
| Types.cs:110:25:110:32 | object creation of type E2 : E2 | Types.cs:115:22:115:31 | access to field Field | Types.cs:115:22:115:31 | access to field Field | $@ | Types.cs:115:22:115:31 | access to field Field | access to field Field |
| Types.cs:110:25:110:32 | object creation of type E2 : Types.E<D>.E2 | Types.cs:115:22:115:31 | access to field Field | Types.cs:115:22:115:31 | access to field Field | $@ | Types.cs:115:22:115:31 | access to field Field | access to field Field |
| Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:122:22:122:31 | call to method Through | Types.cs:122:22:122:31 | call to method Through | $@ | Types.cs:122:22:122:31 | call to method Through | call to method Through |
| Types.cs:121:26:121:33 | object creation of type E2 : E2 | Types.cs:123:22:123:32 | call to method Through | Types.cs:123:22:123:32 | call to method Through | $@ | Types.cs:123:22:123:32 | call to method Through | call to method Through |
| Types.cs:121:26:121:33 | object creation of type E2 : Types.E<D>.E2 | Types.cs:123:22:123:32 | call to method Through | Types.cs:123:22:123:32 | call to method Through | $@ | Types.cs:123:22:123:32 | call to method Through | call to method Through |

View File

@@ -27,3 +27,4 @@
| overrides.cs:268:29:268:36 | Property | overrides.cs:216:13:216:20 | Property |
| overrides.cs:269:29:269:32 | Item | overrides.cs:217:13:217:16 | Item |
| overrides.cs:270:44:270:48 | Event | overrides.cs:218:28:218:32 | Event |
| overrides.cs:284:25:284:28 | M | overrides.cs:279:18:279:21 | M |

View File

@@ -9,3 +9,4 @@
| overrides.cs:249:22:249:25 | M | overrides.cs:247:11:247:12 | A6 | overrides.cs:162:11:162:14 | M | overrides.cs:160:22:160:26 | I2<Object[]> |
| overrides.cs:259:27:259:30 | M | overrides.cs:257:11:257:12 | A8 | overrides.cs:223:26:223:29 | M | overrides.cs:221:11:221:12 | A1 |
| overrides.cs:267:27:267:30 | M | overrides.cs:265:11:265:12 | A9 | overrides.cs:223:26:223:29 | M | overrides.cs:221:11:221:12 | A1 |
| overrides.cs:284:25:284:28 | M | overrides.cs:282:15:282:17 | A10 | overrides.cs:279:18:279:21 | M | overrides.cs:277:19:277:20 | I6 |

View File

@@ -47,3 +47,4 @@
| overrides.G2.M<S>(string, S) | overrides.G.M<S>(string, S) | overrides |
| overrides.G.M<S>(string, S) | overrides.I2<String>.M<S>(string, S) | implements |
| overrides.H<>.M<S>(TA, S) | overrides.I2<TA>.M<S>(TA, S) | implements |
| overrides.Outer<>.A10.M<T>(Inner) | overrides.Outer<>.I6.M<T>(Inner) | implements |

View File

@@ -269,6 +269,23 @@ namespace overrides
public override int this[int x] { get { return x; } } // overrides A2.Item
public override event EventHandler Event; // overrides A2.Event
}
class Outer<T>
{
class Inner { }
interface I6
{
void M<T>(Outer<T>.Inner x);
}
class A10
{
public void M<T>(Outer<T>.Inner x) { } // implements I6.M (via A11)
}
class A11 : A10, I6 { }
}
}
// semmle-extractor-options: /r:System.Dynamic.Runtime.dll /r:System.Linq.Expressions.dll

View File

@@ -1,6 +1,7 @@
interface I1 { }
struct S1 { } struct S2 { }
struct S1 { }
struct S2 { }
class C0 { }
class C1<T1> { }
@@ -31,3 +32,19 @@ class Tuples<T8, T9>
static (T8, T9) t4;
static (T8 a, T9 b) t5 = t4;
}
class Nested<T10>
{
class NestedA<T11> { }
class NestedB
{
public class NestedC<T12> { }
}
Nested<int>.NestedA<string> x1;
Nested<string>.NestedA<int> x2;
Nested<int>.NestedB x3;
Nested<string>.NestedB x4;
Nested<int>.NestedB.NestedC<bool> x5;
Nested<string>.NestedB.NestedC<decimal> x6;
}

View File

@@ -1,298 +1,378 @@
constrainedTypeParameterSubsumes
| Unification.cs:7:10:7:11 | T2 | Unification.cs:3:8:3:9 | S1 |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:3:22:3:23 | S2 |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:7:10:7:11 | T2 |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:11:25:11:27 | T6d |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:28:12:28:20 | (T8,Int32) |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:29:12:29:24 | (String,Int32) |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:30:12:30:23 | (String,T9) |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:31:12:31:19 | (T8,T9) |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:32:12:32:23 | (T8,T9) |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:1:11:1:12 | I1 |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:5:7:5:8 | C0 |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<C0> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<S1> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<S2> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2<S1> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2<S2> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<C1<S1>> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<C2<S1>> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<C2<S2>> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<T6b> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<Tm> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:10:8:11 | T3 |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:7:9:12 | C4<> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:7:9:12 | C4<C1<C0>> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:10:9:11 | T4 |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:7:10:12 | C5<> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:7:10:12 | C5<C2<S1>> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:10:10:11 | T5 |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6<,,,> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6<C1<S1>,C2<S1>,C3<C2<S1>>,S1> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6<C2<S2>,C2<S2>,C3<C2<S2>>,S2> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6<C2<S2>,Tm,C3<Tm>,S2> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:10:11:12 | T6a |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:15:11:17 | T6b |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:20:11:22 | T6c |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:13:7:13:24 | ConstructSomeTypes |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:23:12:23:13 | Tm |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:26:7:26:20 | Tuples<,> |
| Unification.cs:9:10:9:11 | T4 | Unification.cs:6:7:6:12 | C1<C0> |
| Unification.cs:9:10:9:11 | T4 | Unification.cs:9:10:9:11 | T4 |
| Unification.cs:10:10:10:11 | T5 | Unification.cs:7:7:7:12 | C2<S1> |
| Unification.cs:10:10:10:11 | T5 | Unification.cs:10:10:10:11 | T5 |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<C0> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<S1> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<S2> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2<S1> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2<S2> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:9:10:9:11 | T4 |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:10:10:10:11 | T5 |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:11:10:11:12 | T6a |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:11:15:11:17 | T6b |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:23:12:23:13 | Tm |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2<S1> |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2<S2> |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:10:10:10:11 | T5 |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:11:15:11:17 | T6b |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:23:12:23:13 | Tm |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<C1<S1>> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<C2<S1>> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<C2<S2>> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<T6b> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<Tm> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:11:20:11:22 | T6c |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:3:8:3:9 | S1 |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:3:22:3:23 | S2 |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:7:10:7:11 | T2 |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:11:25:11:27 | T6d |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:28:12:28:20 | (T8,Int32) |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:29:12:29:24 | (String,Int32) |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:30:12:30:23 | (String,T9) |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:31:12:31:19 | (T8,T9) |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:32:12:32:23 | (T8,T9) |
| Unification.cs:23:12:23:13 | Tm | Unification.cs:7:7:7:12 | C2<S2> |
| Unification.cs:23:12:23:13 | Tm | Unification.cs:23:12:23:13 | Tm |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:3:8:3:9 | S1 |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:4:8:4:9 | S2 |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:8:10:8:11 | T2 |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:12:25:12:27 | T6d |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:29:12:29:20 | (T8, int) |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:30:12:30:24 | (string, int) |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:31:12:31:23 | (string, T9) |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:32:12:32:19 | (T8, T9) |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:33:12:33:23 | (T8, T9) |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:1:11:1:12 | I1 |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:6:7:6:8 | C0 |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<C0> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<S1> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<S2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:8:7:8:12 | C2<S1> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:8:7:8:12 | C2<S2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<C1<S1>> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<C2<S1>> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<C2<S2>> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<T3> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<T6b> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<Tm> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:10:9:11 | T3 |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:10:7:10:12 | C4<C1<C0>> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:10:7:10:12 | C4<T4> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:10:10:10:11 | T4 |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:11:7:11:12 | C5<C2<S1>> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:11:7:11:12 | C5<T5> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:11:10:11:11 | T5 |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:7:12:28 | C6<C1<S1>, C2<S1>, C3<C2<S1>>, S1> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:7:12:28 | C6<C2<S2>, C2<S2>, C3<C2<S2>>, S2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:7:12:28 | C6<C2<S2>, Tm, C3<Tm>, S2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:7:12:28 | C6<T6a, T6b, T6c, T6d> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:10:12:12 | T6a |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:15:12:17 | T6b |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:20:12:22 | T6c |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:14:7:14:24 | ConstructSomeTypes |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:24:12:24:13 | Tm |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:27:7:27:20 | Tuples<T8, T9> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:36:7:36:17 | Nested<Int32> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:36:7:36:17 | Nested<String> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:36:7:36:17 | Nested<T10> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<String> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<T11> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:38:11:38:22 | Nested<String>.NestedA<Int32> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:38:11:38:22 | Nested<String>.NestedA<T11> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:39:11:39:17 | Nested<>.NestedB |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:39:11:39:17 | Nested<Int32>.NestedB |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:39:11:39:17 | Nested<String>.NestedB |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<Boolean> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<T12> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<Decimal> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<T12> |
| Unification.cs:10:10:10:11 | T4 | Unification.cs:7:7:7:12 | C1<C0> |
| Unification.cs:10:10:10:11 | T4 | Unification.cs:10:10:10:11 | T4 |
| Unification.cs:11:10:11:11 | T5 | Unification.cs:8:7:8:12 | C2<S1> |
| Unification.cs:11:10:11:11 | T5 | Unification.cs:11:10:11:11 | T5 |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<C0> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<S1> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<S2> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:8:7:8:12 | C2<S1> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:8:7:8:12 | C2<S2> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:10:10:10:11 | T4 |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:11:10:11:11 | T5 |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:12:10:12:12 | T6a |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:12:15:12:17 | T6b |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:24:12:24:13 | Tm |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:8:7:8:12 | C2<S1> |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:8:7:8:12 | C2<S2> |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:11:10:11:11 | T5 |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:12:15:12:17 | T6b |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:24:12:24:13 | Tm |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<C1<S1>> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<C2<S1>> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<C2<S2>> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<T3> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<T6b> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<Tm> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:12:20:12:22 | T6c |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:3:8:3:9 | S1 |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:4:8:4:9 | S2 |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:8:10:8:11 | T2 |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:12:25:12:27 | T6d |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:29:12:29:20 | (T8, int) |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:30:12:30:24 | (string, int) |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:31:12:31:23 | (string, T9) |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:32:12:32:19 | (T8, T9) |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:33:12:33:23 | (T8, T9) |
| Unification.cs:24:12:24:13 | Tm | Unification.cs:8:7:8:12 | C2<S2> |
| Unification.cs:24:12:24:13 | Tm | Unification.cs:24:12:24:13 | Tm |
constrainedTypeParameterSubsumptionImpliesUnification
constrainedTypeParameterUnifiable
| Unification.cs:7:10:7:11 | T2 | Unification.cs:3:8:3:9 | S1 |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:3:22:3:23 | S2 |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:7:10:7:11 | T2 |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:11:25:11:27 | T6d |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:28:12:28:20 | (T8,Int32) |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:29:12:29:24 | (String,Int32) |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:30:12:30:23 | (String,T9) |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:31:12:31:19 | (T8,T9) |
| Unification.cs:7:10:7:11 | T2 | Unification.cs:32:12:32:23 | (T8,T9) |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:1:11:1:12 | I1 |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:5:7:5:8 | C0 |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<C0> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<S1> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<S2> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2<S1> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2<S2> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<C1<S1>> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<C2<S1>> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<C2<S2>> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<T6b> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<Tm> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:10:8:11 | T3 |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:7:9:12 | C4<> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:7:9:12 | C4<C1<C0>> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:10:9:11 | T4 |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:7:10:12 | C5<> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:7:10:12 | C5<C2<S1>> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:10:10:11 | T5 |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6<,,,> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6<C1<S1>,C2<S1>,C3<C2<S1>>,S1> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6<C2<S2>,C2<S2>,C3<C2<S2>>,S2> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6<C2<S2>,Tm,C3<Tm>,S2> |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:10:11:12 | T6a |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:15:11:17 | T6b |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:20:11:22 | T6c |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:13:7:13:24 | ConstructSomeTypes |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:23:12:23:13 | Tm |
| Unification.cs:8:10:8:11 | T3 | Unification.cs:26:7:26:20 | Tuples<,> |
| Unification.cs:9:10:9:11 | T4 | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:9:10:9:11 | T4 | Unification.cs:6:7:6:12 | C1<C0> |
| Unification.cs:9:10:9:11 | T4 | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:9:10:9:11 | T4 | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:9:10:9:11 | T4 | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:9:10:9:11 | T4 | Unification.cs:9:10:9:11 | T4 |
| Unification.cs:9:10:9:11 | T4 | Unification.cs:11:10:11:12 | T6a |
| Unification.cs:9:10:9:11 | T4 | Unification.cs:11:15:11:17 | T6b |
| Unification.cs:10:10:10:11 | T5 | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:10:10:10:11 | T5 | Unification.cs:7:7:7:12 | C2<S1> |
| Unification.cs:10:10:10:11 | T5 | Unification.cs:10:10:10:11 | T5 |
| Unification.cs:10:10:10:11 | T5 | Unification.cs:11:15:11:17 | T6b |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<C0> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<S1> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<S2> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2<S1> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2<S2> |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:9:10:9:11 | T4 |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:10:10:10:11 | T5 |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:11:10:11:12 | T6a |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:11:15:11:17 | T6b |
| Unification.cs:11:10:11:12 | T6a | Unification.cs:23:12:23:13 | Tm |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2<S1> |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2<S2> |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:10:10:10:11 | T5 |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:11:15:11:17 | T6b |
| Unification.cs:11:15:11:17 | T6b | Unification.cs:23:12:23:13 | Tm |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<C1<S1>> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<C2<S1>> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<C2<S2>> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<T6b> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<Tm> |
| Unification.cs:11:20:11:22 | T6c | Unification.cs:11:20:11:22 | T6c |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:3:8:3:9 | S1 |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:3:22:3:23 | S2 |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:7:10:7:11 | T2 |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:11:25:11:27 | T6d |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:28:12:28:20 | (T8,Int32) |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:29:12:29:24 | (String,Int32) |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:30:12:30:23 | (String,T9) |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:31:12:31:19 | (T8,T9) |
| Unification.cs:11:25:11:27 | T6d | Unification.cs:32:12:32:23 | (T8,T9) |
| Unification.cs:23:12:23:13 | Tm | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:23:12:23:13 | Tm | Unification.cs:7:7:7:12 | C2<S2> |
| Unification.cs:23:12:23:13 | Tm | Unification.cs:23:12:23:13 | Tm |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:3:8:3:9 | S1 |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:4:8:4:9 | S2 |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:8:10:8:11 | T2 |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:12:25:12:27 | T6d |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:29:12:29:20 | (T8, int) |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:30:12:30:24 | (string, int) |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:31:12:31:23 | (string, T9) |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:32:12:32:19 | (T8, T9) |
| Unification.cs:8:10:8:11 | T2 | Unification.cs:33:12:33:23 | (T8, T9) |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:1:11:1:12 | I1 |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:6:7:6:8 | C0 |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<C0> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<S1> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<S2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:8:7:8:12 | C2<S1> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:8:7:8:12 | C2<S2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<C1<S1>> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<C2<S1>> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<C2<S2>> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<T3> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<T6b> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:7:9:12 | C3<Tm> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:9:10:9:11 | T3 |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:10:7:10:12 | C4<C1<C0>> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:10:7:10:12 | C4<T4> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:10:10:10:11 | T4 |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:11:7:11:12 | C5<C2<S1>> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:11:7:11:12 | C5<T5> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:11:10:11:11 | T5 |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:7:12:28 | C6<C1<S1>, C2<S1>, C3<C2<S1>>, S1> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:7:12:28 | C6<C2<S2>, C2<S2>, C3<C2<S2>>, S2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:7:12:28 | C6<C2<S2>, Tm, C3<Tm>, S2> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:7:12:28 | C6<T6a, T6b, T6c, T6d> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:10:12:12 | T6a |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:15:12:17 | T6b |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:12:20:12:22 | T6c |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:14:7:14:24 | ConstructSomeTypes |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:24:12:24:13 | Tm |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:27:7:27:20 | Tuples<T8, T9> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:36:7:36:17 | Nested<Int32> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:36:7:36:17 | Nested<String> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:36:7:36:17 | Nested<T10> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<String> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<T11> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:38:11:38:22 | Nested<String>.NestedA<Int32> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:38:11:38:22 | Nested<String>.NestedA<T11> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:39:11:39:17 | Nested<>.NestedB |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:39:11:39:17 | Nested<Int32>.NestedB |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:39:11:39:17 | Nested<String>.NestedB |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<Boolean> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<T12> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<Decimal> |
| Unification.cs:9:10:9:11 | T3 | Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<T12> |
| Unification.cs:10:10:10:11 | T4 | Unification.cs:7:7:7:12 | C1<C0> |
| Unification.cs:10:10:10:11 | T4 | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:10:10:10:11 | T4 | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:10:10:10:11 | T4 | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:10:10:10:11 | T4 | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:10:10:10:11 | T4 | Unification.cs:10:10:10:11 | T4 |
| Unification.cs:10:10:10:11 | T4 | Unification.cs:12:10:12:12 | T6a |
| Unification.cs:10:10:10:11 | T4 | Unification.cs:12:15:12:17 | T6b |
| Unification.cs:11:10:11:11 | T5 | Unification.cs:8:7:8:12 | C2<S1> |
| Unification.cs:11:10:11:11 | T5 | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:11:10:11:11 | T5 | Unification.cs:11:10:11:11 | T5 |
| Unification.cs:11:10:11:11 | T5 | Unification.cs:12:15:12:17 | T6b |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<C0> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<S1> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<S2> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:8:7:8:12 | C2<S1> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:8:7:8:12 | C2<S2> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:10:10:10:11 | T4 |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:11:10:11:11 | T5 |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:12:10:12:12 | T6a |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:12:15:12:17 | T6b |
| Unification.cs:12:10:12:12 | T6a | Unification.cs:24:12:24:13 | Tm |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:8:7:8:12 | C2<S1> |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:8:7:8:12 | C2<S2> |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:11:10:11:11 | T5 |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:12:15:12:17 | T6b |
| Unification.cs:12:15:12:17 | T6b | Unification.cs:24:12:24:13 | Tm |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<C1<S1>> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<C2<S1>> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<C2<S2>> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<T3> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<T6b> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:9:7:9:12 | C3<Tm> |
| Unification.cs:12:20:12:22 | T6c | Unification.cs:12:20:12:22 | T6c |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:3:8:3:9 | S1 |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:4:8:4:9 | S2 |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:8:10:8:11 | T2 |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:12:25:12:27 | T6d |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:29:12:29:20 | (T8, int) |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:30:12:30:24 | (string, int) |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:31:12:31:23 | (string, T9) |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:32:12:32:19 | (T8, T9) |
| Unification.cs:12:25:12:27 | T6d | Unification.cs:33:12:33:23 | (T8, T9) |
| Unification.cs:24:12:24:13 | Tm | Unification.cs:8:7:8:12 | C2<S2> |
| Unification.cs:24:12:24:13 | Tm | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:24:12:24:13 | Tm | Unification.cs:24:12:24:13 | Tm |
subsumes
| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1<C0> |
| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1<S1> |
| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1<S2> |
| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:6:7:6:12 | C1<C0> | Unification.cs:6:7:6:12 | C1<C0> |
| Unification.cs:6:7:6:12 | C1<S1> | Unification.cs:6:7:6:12 | C1<S1> |
| Unification.cs:6:7:6:12 | C1<S2> | Unification.cs:6:7:6:12 | C1<S2> |
| Unification.cs:6:7:6:12 | C1<T2> | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:6:7:6:12 | C1<T2> | Unification.cs:6:7:6:12 | C1<C0> |
| Unification.cs:6:7:6:12 | C1<T2> | Unification.cs:6:7:6:12 | C1<S1> |
| Unification.cs:6:7:6:12 | C1<T2> | Unification.cs:6:7:6:12 | C1<S2> |
| Unification.cs:6:7:6:12 | C1<T2> | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:6:7:6:12 | C1<T2> | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:6:7:6:12 | C1<T6d> | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:6:7:6:12 | C1<T6d> | Unification.cs:6:7:6:12 | C1<C0> |
| Unification.cs:6:7:6:12 | C1<T6d> | Unification.cs:6:7:6:12 | C1<S1> |
| Unification.cs:6:7:6:12 | C1<T6d> | Unification.cs:6:7:6:12 | C1<S2> |
| Unification.cs:6:7:6:12 | C1<T6d> | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:6:7:6:12 | C1<T6d> | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:7:7:7:12 | C2<> | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:7:7:7:12 | C2<> | Unification.cs:7:7:7:12 | C2<S1> |
| Unification.cs:7:7:7:12 | C2<> | Unification.cs:7:7:7:12 | C2<S2> |
| Unification.cs:7:7:7:12 | C2<S1> | Unification.cs:7:7:7:12 | C2<S1> |
| Unification.cs:7:7:7:12 | C2<S2> | Unification.cs:7:7:7:12 | C2<S2> |
| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3<> |
| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3<C1<S1>> |
| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3<C2<S1>> |
| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3<C2<S2>> |
| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3<T6b> |
| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3<Tm> |
| Unification.cs:8:7:8:12 | C3<C1<S1>> | Unification.cs:8:7:8:12 | C3<C1<S1>> |
| Unification.cs:8:7:8:12 | C3<C2<S1>> | Unification.cs:8:7:8:12 | C3<C2<S1>> |
| Unification.cs:8:7:8:12 | C3<C2<S2>> | Unification.cs:8:7:8:12 | C3<C2<S2>> |
| Unification.cs:8:7:8:12 | C3<T6b> | Unification.cs:8:7:8:12 | C3<> |
| Unification.cs:8:7:8:12 | C3<T6b> | Unification.cs:8:7:8:12 | C3<C1<S1>> |
| Unification.cs:8:7:8:12 | C3<T6b> | Unification.cs:8:7:8:12 | C3<C2<S1>> |
| Unification.cs:8:7:8:12 | C3<T6b> | Unification.cs:8:7:8:12 | C3<C2<S2>> |
| Unification.cs:8:7:8:12 | C3<T6b> | Unification.cs:8:7:8:12 | C3<T6b> |
| Unification.cs:8:7:8:12 | C3<T6b> | Unification.cs:8:7:8:12 | C3<Tm> |
| Unification.cs:8:7:8:12 | C3<Tm> | Unification.cs:8:7:8:12 | C3<> |
| Unification.cs:8:7:8:12 | C3<Tm> | Unification.cs:8:7:8:12 | C3<C1<S1>> |
| Unification.cs:8:7:8:12 | C3<Tm> | Unification.cs:8:7:8:12 | C3<C2<S1>> |
| Unification.cs:8:7:8:12 | C3<Tm> | Unification.cs:8:7:8:12 | C3<C2<S2>> |
| Unification.cs:8:7:8:12 | C3<Tm> | Unification.cs:8:7:8:12 | C3<T6b> |
| Unification.cs:8:7:8:12 | C3<Tm> | Unification.cs:8:7:8:12 | C3<Tm> |
| Unification.cs:9:7:9:12 | C4<> | Unification.cs:9:7:9:12 | C4<> |
| Unification.cs:9:7:9:12 | C4<> | Unification.cs:9:7:9:12 | C4<C1<C0>> |
| Unification.cs:9:7:9:12 | C4<C1<C0>> | Unification.cs:9:7:9:12 | C4<C1<C0>> |
| Unification.cs:10:7:10:12 | C5<> | Unification.cs:10:7:10:12 | C5<> |
| Unification.cs:10:7:10:12 | C5<> | Unification.cs:10:7:10:12 | C5<C2<S1>> |
| Unification.cs:10:7:10:12 | C5<C2<S1>> | Unification.cs:10:7:10:12 | C5<C2<S1>> |
| Unification.cs:11:7:11:28 | C6<,,,> | Unification.cs:11:7:11:28 | C6<,,,> |
| Unification.cs:11:7:11:28 | C6<,,,> | Unification.cs:11:7:11:28 | C6<C1<S1>,C2<S1>,C3<C2<S1>>,S1> |
| Unification.cs:11:7:11:28 | C6<,,,> | Unification.cs:11:7:11:28 | C6<C2<S2>,C2<S2>,C3<C2<S2>>,S2> |
| Unification.cs:11:7:11:28 | C6<,,,> | Unification.cs:11:7:11:28 | C6<C2<S2>,Tm,C3<Tm>,S2> |
| Unification.cs:11:7:11:28 | C6<C1<S1>,C2<S1>,C3<C2<S1>>,S1> | Unification.cs:11:7:11:28 | C6<C1<S1>,C2<S1>,C3<C2<S1>>,S1> |
| Unification.cs:11:7:11:28 | C6<C2<S2>,C2<S2>,C3<C2<S2>>,S2> | Unification.cs:11:7:11:28 | C6<C2<S2>,C2<S2>,C3<C2<S2>>,S2> |
| Unification.cs:11:7:11:28 | C6<C2<S2>,Tm,C3<Tm>,S2> | Unification.cs:11:7:11:28 | C6<C2<S2>,C2<S2>,C3<C2<S2>>,S2> |
| Unification.cs:11:7:11:28 | C6<C2<S2>,Tm,C3<Tm>,S2> | Unification.cs:11:7:11:28 | C6<C2<S2>,Tm,C3<Tm>,S2> |
| Unification.cs:26:7:26:20 | Tuples<,> | Unification.cs:26:7:26:20 | Tuples<,> |
| Unification.cs:28:12:28:20 | (T8,Int32) | Unification.cs:28:12:28:20 | (T8,Int32) |
| Unification.cs:28:12:28:20 | (T8,Int32) | Unification.cs:29:12:29:24 | (String,Int32) |
| Unification.cs:29:12:29:24 | (String,Int32) | Unification.cs:29:12:29:24 | (String,Int32) |
| Unification.cs:30:12:30:23 | (String,T9) | Unification.cs:29:12:29:24 | (String,Int32) |
| Unification.cs:30:12:30:23 | (String,T9) | Unification.cs:30:12:30:23 | (String,T9) |
| Unification.cs:31:12:31:19 | (T8,T9) | Unification.cs:28:12:28:20 | (T8,Int32) |
| Unification.cs:31:12:31:19 | (T8,T9) | Unification.cs:29:12:29:24 | (String,Int32) |
| Unification.cs:31:12:31:19 | (T8,T9) | Unification.cs:30:12:30:23 | (String,T9) |
| Unification.cs:31:12:31:19 | (T8,T9) | Unification.cs:31:12:31:19 | (T8,T9) |
| Unification.cs:31:12:31:19 | (T8,T9) | Unification.cs:32:12:32:23 | (T8,T9) |
| Unification.cs:32:12:32:23 | (T8,T9) | Unification.cs:28:12:28:20 | (T8,Int32) |
| Unification.cs:32:12:32:23 | (T8,T9) | Unification.cs:29:12:29:24 | (String,Int32) |
| Unification.cs:32:12:32:23 | (T8,T9) | Unification.cs:30:12:30:23 | (String,T9) |
| Unification.cs:32:12:32:23 | (T8,T9) | Unification.cs:31:12:31:19 | (T8,T9) |
| Unification.cs:32:12:32:23 | (T8,T9) | Unification.cs:32:12:32:23 | (T8,T9) |
| Unification.cs:7:7:7:12 | C1<C0> | Unification.cs:7:7:7:12 | C1<C0> |
| Unification.cs:7:7:7:12 | C1<S1> | Unification.cs:7:7:7:12 | C1<S1> |
| Unification.cs:7:7:7:12 | C1<S2> | Unification.cs:7:7:7:12 | C1<S2> |
| Unification.cs:7:7:7:12 | C1<T1> | Unification.cs:7:7:7:12 | C1<C0> |
| Unification.cs:7:7:7:12 | C1<T1> | Unification.cs:7:7:7:12 | C1<S1> |
| Unification.cs:7:7:7:12 | C1<T1> | Unification.cs:7:7:7:12 | C1<S2> |
| Unification.cs:7:7:7:12 | C1<T1> | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:7:7:7:12 | C1<T1> | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:7:7:7:12 | C1<T1> | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:7:7:7:12 | C1<T2> | Unification.cs:7:7:7:12 | C1<C0> |
| Unification.cs:7:7:7:12 | C1<T2> | Unification.cs:7:7:7:12 | C1<S1> |
| Unification.cs:7:7:7:12 | C1<T2> | Unification.cs:7:7:7:12 | C1<S2> |
| Unification.cs:7:7:7:12 | C1<T2> | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:7:7:7:12 | C1<T2> | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:7:7:7:12 | C1<T2> | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:7:7:7:12 | C1<T6d> | Unification.cs:7:7:7:12 | C1<C0> |
| Unification.cs:7:7:7:12 | C1<T6d> | Unification.cs:7:7:7:12 | C1<S1> |
| Unification.cs:7:7:7:12 | C1<T6d> | Unification.cs:7:7:7:12 | C1<S2> |
| Unification.cs:7:7:7:12 | C1<T6d> | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:7:7:7:12 | C1<T6d> | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:7:7:7:12 | C1<T6d> | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:8:7:8:12 | C2<S1> | Unification.cs:8:7:8:12 | C2<S1> |
| Unification.cs:8:7:8:12 | C2<S2> | Unification.cs:8:7:8:12 | C2<S2> |
| Unification.cs:8:7:8:12 | C2<T2> | Unification.cs:8:7:8:12 | C2<S1> |
| Unification.cs:8:7:8:12 | C2<T2> | Unification.cs:8:7:8:12 | C2<S2> |
| Unification.cs:8:7:8:12 | C2<T2> | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:9:7:9:12 | C3<C1<S1>> | Unification.cs:9:7:9:12 | C3<C1<S1>> |
| Unification.cs:9:7:9:12 | C3<C2<S1>> | Unification.cs:9:7:9:12 | C3<C2<S1>> |
| Unification.cs:9:7:9:12 | C3<C2<S2>> | Unification.cs:9:7:9:12 | C3<C2<S2>> |
| Unification.cs:9:7:9:12 | C3<T3> | Unification.cs:9:7:9:12 | C3<C1<S1>> |
| Unification.cs:9:7:9:12 | C3<T3> | Unification.cs:9:7:9:12 | C3<C2<S1>> |
| Unification.cs:9:7:9:12 | C3<T3> | Unification.cs:9:7:9:12 | C3<C2<S2>> |
| Unification.cs:9:7:9:12 | C3<T3> | Unification.cs:9:7:9:12 | C3<T3> |
| Unification.cs:9:7:9:12 | C3<T3> | Unification.cs:9:7:9:12 | C3<T6b> |
| Unification.cs:9:7:9:12 | C3<T3> | Unification.cs:9:7:9:12 | C3<Tm> |
| Unification.cs:9:7:9:12 | C3<T6b> | Unification.cs:9:7:9:12 | C3<C1<S1>> |
| Unification.cs:9:7:9:12 | C3<T6b> | Unification.cs:9:7:9:12 | C3<C2<S1>> |
| Unification.cs:9:7:9:12 | C3<T6b> | Unification.cs:9:7:9:12 | C3<C2<S2>> |
| Unification.cs:9:7:9:12 | C3<T6b> | Unification.cs:9:7:9:12 | C3<T3> |
| Unification.cs:9:7:9:12 | C3<T6b> | Unification.cs:9:7:9:12 | C3<T6b> |
| Unification.cs:9:7:9:12 | C3<T6b> | Unification.cs:9:7:9:12 | C3<Tm> |
| Unification.cs:9:7:9:12 | C3<Tm> | Unification.cs:9:7:9:12 | C3<C1<S1>> |
| Unification.cs:9:7:9:12 | C3<Tm> | Unification.cs:9:7:9:12 | C3<C2<S1>> |
| Unification.cs:9:7:9:12 | C3<Tm> | Unification.cs:9:7:9:12 | C3<C2<S2>> |
| Unification.cs:9:7:9:12 | C3<Tm> | Unification.cs:9:7:9:12 | C3<T3> |
| Unification.cs:9:7:9:12 | C3<Tm> | Unification.cs:9:7:9:12 | C3<T6b> |
| Unification.cs:9:7:9:12 | C3<Tm> | Unification.cs:9:7:9:12 | C3<Tm> |
| Unification.cs:10:7:10:12 | C4<C1<C0>> | Unification.cs:10:7:10:12 | C4<C1<C0>> |
| Unification.cs:10:7:10:12 | C4<T4> | Unification.cs:10:7:10:12 | C4<C1<C0>> |
| Unification.cs:10:7:10:12 | C4<T4> | Unification.cs:10:7:10:12 | C4<T4> |
| Unification.cs:11:7:11:12 | C5<C2<S1>> | Unification.cs:11:7:11:12 | C5<C2<S1>> |
| Unification.cs:11:7:11:12 | C5<T5> | Unification.cs:11:7:11:12 | C5<C2<S1>> |
| Unification.cs:11:7:11:12 | C5<T5> | Unification.cs:11:7:11:12 | C5<T5> |
| Unification.cs:12:7:12:28 | C6<C1<S1>, C2<S1>, C3<C2<S1>>, S1> | Unification.cs:12:7:12:28 | C6<C1<S1>, C2<S1>, C3<C2<S1>>, S1> |
| Unification.cs:12:7:12:28 | C6<C2<S2>, C2<S2>, C3<C2<S2>>, S2> | Unification.cs:12:7:12:28 | C6<C2<S2>, C2<S2>, C3<C2<S2>>, S2> |
| Unification.cs:12:7:12:28 | C6<C2<S2>, Tm, C3<Tm>, S2> | Unification.cs:12:7:12:28 | C6<C2<S2>, C2<S2>, C3<C2<S2>>, S2> |
| Unification.cs:12:7:12:28 | C6<C2<S2>, Tm, C3<Tm>, S2> | Unification.cs:12:7:12:28 | C6<C2<S2>, Tm, C3<Tm>, S2> |
| Unification.cs:12:7:12:28 | C6<T6a, T6b, T6c, T6d> | Unification.cs:12:7:12:28 | C6<C1<S1>, C2<S1>, C3<C2<S1>>, S1> |
| Unification.cs:12:7:12:28 | C6<T6a, T6b, T6c, T6d> | Unification.cs:12:7:12:28 | C6<C2<S2>, C2<S2>, C3<C2<S2>>, S2> |
| Unification.cs:12:7:12:28 | C6<T6a, T6b, T6c, T6d> | Unification.cs:12:7:12:28 | C6<C2<S2>, Tm, C3<Tm>, S2> |
| Unification.cs:12:7:12:28 | C6<T6a, T6b, T6c, T6d> | Unification.cs:12:7:12:28 | C6<T6a, T6b, T6c, T6d> |
| Unification.cs:27:7:27:20 | Tuples<T8, T9> | Unification.cs:27:7:27:20 | Tuples<T8, T9> |
| Unification.cs:29:12:29:20 | (T8, int) | Unification.cs:29:12:29:20 | (T8, int) |
| Unification.cs:29:12:29:20 | (T8, int) | Unification.cs:30:12:30:24 | (string, int) |
| Unification.cs:30:12:30:24 | (string, int) | Unification.cs:30:12:30:24 | (string, int) |
| Unification.cs:31:12:31:23 | (string, T9) | Unification.cs:30:12:30:24 | (string, int) |
| Unification.cs:31:12:31:23 | (string, T9) | Unification.cs:31:12:31:23 | (string, T9) |
| Unification.cs:32:12:32:19 | (T8, T9) | Unification.cs:29:12:29:20 | (T8, int) |
| Unification.cs:32:12:32:19 | (T8, T9) | Unification.cs:30:12:30:24 | (string, int) |
| Unification.cs:32:12:32:19 | (T8, T9) | Unification.cs:31:12:31:23 | (string, T9) |
| Unification.cs:32:12:32:19 | (T8, T9) | Unification.cs:32:12:32:19 | (T8, T9) |
| Unification.cs:32:12:32:19 | (T8, T9) | Unification.cs:33:12:33:23 | (T8, T9) |
| Unification.cs:33:12:33:23 | (T8, T9) | Unification.cs:29:12:29:20 | (T8, int) |
| Unification.cs:33:12:33:23 | (T8, T9) | Unification.cs:30:12:30:24 | (string, int) |
| Unification.cs:33:12:33:23 | (T8, T9) | Unification.cs:31:12:31:23 | (string, T9) |
| Unification.cs:33:12:33:23 | (T8, T9) | Unification.cs:32:12:32:19 | (T8, T9) |
| Unification.cs:33:12:33:23 | (T8, T9) | Unification.cs:33:12:33:23 | (T8, T9) |
| Unification.cs:36:7:36:17 | Nested<Int32> | Unification.cs:36:7:36:17 | Nested<Int32> |
| Unification.cs:36:7:36:17 | Nested<String> | Unification.cs:36:7:36:17 | Nested<String> |
| Unification.cs:36:7:36:17 | Nested<T10> | Unification.cs:36:7:36:17 | Nested<Int32> |
| Unification.cs:36:7:36:17 | Nested<T10> | Unification.cs:36:7:36:17 | Nested<String> |
| Unification.cs:36:7:36:17 | Nested<T10> | Unification.cs:36:7:36:17 | Nested<T10> |
| Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> |
| Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<String> |
| Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<T11> |
| Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<String>.NestedA<Int32> |
| Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<String>.NestedA<T11> |
| Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<String> | Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<String> |
| Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<String> |
| Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<T11> |
| Unification.cs:38:11:38:22 | Nested<String>.NestedA<Int32> | Unification.cs:38:11:38:22 | Nested<String>.NestedA<Int32> |
| Unification.cs:38:11:38:22 | Nested<String>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<String>.NestedA<Int32> |
| Unification.cs:38:11:38:22 | Nested<String>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<String>.NestedA<T11> |
| Unification.cs:39:11:39:17 | Nested<>.NestedB | Unification.cs:39:11:39:17 | Nested<>.NestedB |
| Unification.cs:39:11:39:17 | Nested<>.NestedB | Unification.cs:39:11:39:17 | Nested<Int32>.NestedB |
| Unification.cs:39:11:39:17 | Nested<>.NestedB | Unification.cs:39:11:39:17 | Nested<String>.NestedB |
| Unification.cs:39:11:39:17 | Nested<Int32>.NestedB | Unification.cs:39:11:39:17 | Nested<Int32>.NestedB |
| Unification.cs:39:11:39:17 | Nested<String>.NestedB | Unification.cs:39:11:39:17 | Nested<String>.NestedB |
| Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> |
| Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<Boolean> |
| Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<T12> |
| Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<Decimal> |
| Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<T12> |
| Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<Boolean> | Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<Boolean> |
| Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<Boolean> |
| Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<T12> |
| Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<Decimal> | Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<Decimal> |
| Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<Decimal> |
| Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<T12> |
subsumptionImpliesUnification
unifiable
| Unification.cs:6:7:6:12 | C1<C0> | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:6:7:6:12 | C1<C0> | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:6:7:6:12 | C1<C0> | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:6:7:6:12 | C1<S1> | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:6:7:6:12 | C1<S1> | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:6:7:6:12 | C1<S1> | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:6:7:6:12 | C1<S2> | Unification.cs:6:7:6:12 | C1<> |
| Unification.cs:6:7:6:12 | C1<S2> | Unification.cs:6:7:6:12 | C1<T2> |
| Unification.cs:6:7:6:12 | C1<S2> | Unification.cs:6:7:6:12 | C1<T6d> |
| Unification.cs:7:7:7:12 | C2<S1> | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:7:7:7:12 | C2<S2> | Unification.cs:7:7:7:12 | C2<> |
| Unification.cs:8:7:8:12 | C3<C1<S1>> | Unification.cs:8:7:8:12 | C3<> |
| Unification.cs:8:7:8:12 | C3<C1<S1>> | Unification.cs:8:7:8:12 | C3<T6b> |
| Unification.cs:8:7:8:12 | C3<C1<S1>> | Unification.cs:8:7:8:12 | C3<Tm> |
| Unification.cs:8:7:8:12 | C3<C2<S1>> | Unification.cs:8:7:8:12 | C3<> |
| Unification.cs:8:7:8:12 | C3<C2<S1>> | Unification.cs:8:7:8:12 | C3<T6b> |
| Unification.cs:8:7:8:12 | C3<C2<S1>> | Unification.cs:8:7:8:12 | C3<Tm> |
| Unification.cs:8:7:8:12 | C3<C2<S2>> | Unification.cs:8:7:8:12 | C3<> |
| Unification.cs:8:7:8:12 | C3<C2<S2>> | Unification.cs:8:7:8:12 | C3<T6b> |
| Unification.cs:8:7:8:12 | C3<C2<S2>> | Unification.cs:8:7:8:12 | C3<Tm> |
| Unification.cs:9:7:9:12 | C4<C1<C0>> | Unification.cs:9:7:9:12 | C4<> |
| Unification.cs:10:7:10:12 | C5<C2<S1>> | Unification.cs:10:7:10:12 | C5<> |
| Unification.cs:11:7:11:28 | C6<C1<S1>,C2<S1>,C3<C2<S1>>,S1> | Unification.cs:11:7:11:28 | C6<,,,> |
| Unification.cs:11:7:11:28 | C6<C2<S2>,C2<S2>,C3<C2<S2>>,S2> | Unification.cs:11:7:11:28 | C6<,,,> |
| Unification.cs:11:7:11:28 | C6<C2<S2>,C2<S2>,C3<C2<S2>>,S2> | Unification.cs:11:7:11:28 | C6<C2<S2>,Tm,C3<Tm>,S2> |
| Unification.cs:11:7:11:28 | C6<C2<S2>,Tm,C3<Tm>,S2> | Unification.cs:11:7:11:28 | C6<,,,> |
| Unification.cs:28:12:28:20 | (T8,Int32) | Unification.cs:30:12:30:23 | (String,T9) |
| Unification.cs:28:12:28:20 | (T8,Int32) | Unification.cs:31:12:31:19 | (T8,T9) |
| Unification.cs:28:12:28:20 | (T8,Int32) | Unification.cs:32:12:32:23 | (T8,T9) |
| Unification.cs:29:12:29:24 | (String,Int32) | Unification.cs:28:12:28:20 | (T8,Int32) |
| Unification.cs:29:12:29:24 | (String,Int32) | Unification.cs:30:12:30:23 | (String,T9) |
| Unification.cs:29:12:29:24 | (String,Int32) | Unification.cs:31:12:31:19 | (T8,T9) |
| Unification.cs:29:12:29:24 | (String,Int32) | Unification.cs:32:12:32:23 | (T8,T9) |
| Unification.cs:30:12:30:23 | (String,T9) | Unification.cs:28:12:28:20 | (T8,Int32) |
| Unification.cs:30:12:30:23 | (String,T9) | Unification.cs:31:12:31:19 | (T8,T9) |
| Unification.cs:30:12:30:23 | (String,T9) | Unification.cs:32:12:32:23 | (T8,T9) |
| Unification.cs:7:7:7:12 | C1<C0> | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:7:7:7:12 | C1<C0> | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:7:7:7:12 | C1<C0> | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:7:7:7:12 | C1<S1> | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:7:7:7:12 | C1<S1> | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:7:7:7:12 | C1<S1> | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:7:7:7:12 | C1<S2> | Unification.cs:7:7:7:12 | C1<T1> |
| Unification.cs:7:7:7:12 | C1<S2> | Unification.cs:7:7:7:12 | C1<T2> |
| Unification.cs:7:7:7:12 | C1<S2> | Unification.cs:7:7:7:12 | C1<T6d> |
| Unification.cs:8:7:8:12 | C2<S1> | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:8:7:8:12 | C2<S2> | Unification.cs:8:7:8:12 | C2<T2> |
| Unification.cs:9:7:9:12 | C3<C1<S1>> | Unification.cs:9:7:9:12 | C3<T3> |
| Unification.cs:9:7:9:12 | C3<C1<S1>> | Unification.cs:9:7:9:12 | C3<T6b> |
| Unification.cs:9:7:9:12 | C3<C1<S1>> | Unification.cs:9:7:9:12 | C3<Tm> |
| Unification.cs:9:7:9:12 | C3<C2<S1>> | Unification.cs:9:7:9:12 | C3<T3> |
| Unification.cs:9:7:9:12 | C3<C2<S1>> | Unification.cs:9:7:9:12 | C3<T6b> |
| Unification.cs:9:7:9:12 | C3<C2<S1>> | Unification.cs:9:7:9:12 | C3<Tm> |
| Unification.cs:9:7:9:12 | C3<C2<S2>> | Unification.cs:9:7:9:12 | C3<T3> |
| Unification.cs:9:7:9:12 | C3<C2<S2>> | Unification.cs:9:7:9:12 | C3<T6b> |
| Unification.cs:9:7:9:12 | C3<C2<S2>> | Unification.cs:9:7:9:12 | C3<Tm> |
| Unification.cs:10:7:10:12 | C4<C1<C0>> | Unification.cs:10:7:10:12 | C4<T4> |
| Unification.cs:11:7:11:12 | C5<C2<S1>> | Unification.cs:11:7:11:12 | C5<T5> |
| Unification.cs:12:7:12:28 | C6<C1<S1>, C2<S1>, C3<C2<S1>>, S1> | Unification.cs:12:7:12:28 | C6<T6a, T6b, T6c, T6d> |
| Unification.cs:12:7:12:28 | C6<C2<S2>, C2<S2>, C3<C2<S2>>, S2> | Unification.cs:12:7:12:28 | C6<C2<S2>, Tm, C3<Tm>, S2> |
| Unification.cs:12:7:12:28 | C6<C2<S2>, C2<S2>, C3<C2<S2>>, S2> | Unification.cs:12:7:12:28 | C6<T6a, T6b, T6c, T6d> |
| Unification.cs:12:7:12:28 | C6<C2<S2>, Tm, C3<Tm>, S2> | Unification.cs:12:7:12:28 | C6<T6a, T6b, T6c, T6d> |
| Unification.cs:29:12:29:20 | (T8, int) | Unification.cs:31:12:31:23 | (string, T9) |
| Unification.cs:29:12:29:20 | (T8, int) | Unification.cs:32:12:32:19 | (T8, T9) |
| Unification.cs:29:12:29:20 | (T8, int) | Unification.cs:33:12:33:23 | (T8, T9) |
| Unification.cs:30:12:30:24 | (string, int) | Unification.cs:29:12:29:20 | (T8, int) |
| Unification.cs:30:12:30:24 | (string, int) | Unification.cs:31:12:31:23 | (string, T9) |
| Unification.cs:30:12:30:24 | (string, int) | Unification.cs:32:12:32:19 | (T8, T9) |
| Unification.cs:30:12:30:24 | (string, int) | Unification.cs:33:12:33:23 | (T8, T9) |
| Unification.cs:31:12:31:23 | (string, T9) | Unification.cs:29:12:29:20 | (T8, int) |
| Unification.cs:31:12:31:23 | (string, T9) | Unification.cs:32:12:32:19 | (T8, T9) |
| Unification.cs:31:12:31:23 | (string, T9) | Unification.cs:33:12:33:23 | (T8, T9) |
| Unification.cs:36:7:36:17 | Nested<Int32> | Unification.cs:36:7:36:17 | Nested<T10> |
| Unification.cs:36:7:36:17 | Nested<String> | Unification.cs:36:7:36:17 | Nested<T10> |
| Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<String> | Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> |
| Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<String> | Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<T11> |
| Unification.cs:38:11:38:22 | Nested<Int32>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> |
| Unification.cs:38:11:38:22 | Nested<String>.NestedA<Int32> | Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> |
| Unification.cs:38:11:38:22 | Nested<String>.NestedA<Int32> | Unification.cs:38:11:38:22 | Nested<String>.NestedA<T11> |
| Unification.cs:38:11:38:22 | Nested<String>.NestedA<T11> | Unification.cs:38:11:38:22 | Nested<>.NestedA<T11> |
| Unification.cs:39:11:39:17 | Nested<Int32>.NestedB | Unification.cs:39:11:39:17 | Nested<>.NestedB |
| Unification.cs:39:11:39:17 | Nested<String>.NestedB | Unification.cs:39:11:39:17 | Nested<>.NestedB |
| Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<Boolean> | Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> |
| Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<Boolean> | Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<T12> |
| Unification.cs:41:22:41:33 | Nested<Int32>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> |
| Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<Decimal> | Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> |
| Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<Decimal> | Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<T12> |
| Unification.cs:41:22:41:33 | Nested<String>.NestedB.NestedC<T12> | Unification.cs:41:22:41:33 | Nested<>.NestedB.NestedC<T12> |

View File

@@ -1,10 +1,19 @@
import semmle.code.csharp.Unification
class InterestingType extends Type {
class InterestingType extends @type {
InterestingType() {
this.fromSource() or
this.(Type).fromSource() or
this.(TupleType).getAChild() instanceof InterestingType
}
string toString() {
result = this.(Type).getQualifiedNameWithTypes()
or
not exists(this.(Type).getQualifiedNameWithTypes()) and
result = this.(Type).toStringWithTypes()
}
Location getLocation() { result = this.(Type).getLocation() }
}
query predicate constrainedTypeParameterSubsumes(InterestingType tp, InterestingType t) {
@@ -12,9 +21,7 @@ query predicate constrainedTypeParameterSubsumes(InterestingType tp, Interesting
}
// Should be empty
query predicate constrainedTypeParameterSubsumptionImpliesUnification(
InterestingType tp, InterestingType t
) {
query predicate constrainedTypeParameterSubsumptionImpliesUnification(Type tp, Type t) {
tp.(Unification::ConstrainedTypeParameter).subsumes(t) and
not tp.(Unification::ConstrainedTypeParameter).unifiable(t)
}

View File

@@ -1,42 +1,99 @@
| FormatInvalid.cs:27:24:27:28 | "{ 0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:27:9:27:32 | call to method Format | this |
| FormatInvalid.cs:30:24:30:31 | "{0,--1}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:30:9:30:35 | call to method Format | this |
| FormatInvalid.cs:33:24:33:30 | "{0:{}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:33:9:33:34 | call to method Format | this |
| FormatInvalid.cs:39:27:39:33 | "{{0}-{1}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:39:9:39:40 | call to method Format | this |
| FormatInvalid.cs:42:27:42:28 | "{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:42:9:42:35 | call to method Format | this |
| FormatInvalid.cs:45:24:45:32 | "{foo{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:45:9:45:36 | call to method Format | this |
| FormatInvalid.cs:51:24:51:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:51:9:51:29 | call to method Format | this |
| FormatInvalid.cs:75:24:75:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:75:9:75:29 | call to method Format | this |
| FormatInvalid.cs:76:24:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:30 | call to method Format | this |
| FormatInvalid.cs:77:28:77:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:34 | call to method Format | this |
| FormatInvalid.cs:78:24:78:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:32 | call to method Format | this |
| FormatInvalid.cs:79:24:79:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:35 | call to method Format | this |
| FormatInvalid.cs:80:24:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:38 | call to method Format | this |
| FormatInvalid.cs:82:26:82:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this |
| FormatInvalid.cs:83:26:83:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this |
| FormatInvalid.cs:84:30:84:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this |
| FormatInvalid.cs:85:26:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this |
| FormatInvalid.cs:86:26:86:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this |
| FormatInvalid.cs:87:26:87:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this |
| FormatInvalid.cs:89:28:89:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this |
| FormatInvalid.cs:90:28:90:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this |
| FormatInvalid.cs:91:28:91:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this |
| FormatInvalid.cs:92:28:92:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this |
| FormatInvalid.cs:93:28:93:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this |
| FormatInvalid.cs:95:23:95:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this |
| FormatInvalid.cs:96:23:96:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this |
| FormatInvalid.cs:97:23:97:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this |
| FormatInvalid.cs:98:23:98:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this |
| FormatInvalid.cs:99:23:99:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this |
| FormatInvalid.cs:101:45:101:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this |
| FormatInvalid.cs:102:46:102:47 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this |
| FormatInvalid.cs:103:52:103:53 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this |
| FormatInvalid.cs:104:48:104:49 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this |
| FormatInvalid.cs:105:30:105:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this |
| FormatInvalid.cs:107:24:107:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:107:9:107:29 | call to method Write | this |
| FormatInvalid.cs:108:24:108:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:108:9:108:32 | call to method Write | this |
| FormatInvalid.cs:109:24:109:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:109:9:109:35 | call to method Write | this |
| FormatInvalid.cs:110:24:110:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:110:9:110:38 | call to method Write | this |
| FormatInvalid.cs:115:57:115:58 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:115:9:115:63 | call to method Assert | this |
| FormatInvalid.cs:116:19:116:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:116:9:116:24 | call to method Write | this |
| FormatInvalid.cs:117:41:117:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:117:9:117:47 | call to method Print | this |
| FormatInvalidBad.cs:7:41:7:44 | "class {0} { }" | Invalid format string used in $@ formatting call. | FormatInvalidBad.cs:7:16:7:45 | call to method Format | this |
nodes
| FormatInvalid.cs:9:23:9:27 | "{0}" | semmle.label | "{0}" |
| FormatInvalid.cs:12:23:12:29 | "{0,1}" | semmle.label | "{0,1}" |
| FormatInvalid.cs:15:23:15:31 | "{0, 1}" | semmle.label | "{0, 1}" |
| FormatInvalid.cs:18:23:18:30 | "{0,-1}" | semmle.label | "{0,-1}" |
| FormatInvalid.cs:21:23:21:33 | "{0:0.000}" | semmle.label | "{0:0.000}" |
| FormatInvalid.cs:24:23:24:39 | "{0, -10 :0.000}" | semmle.label | "{0, -10 :0.000}" |
| FormatInvalid.cs:27:23:27:28 | "{ 0}" | semmle.label | "{ 0}" |
| FormatInvalid.cs:30:23:30:31 | "{0,--1}" | semmle.label | "{0,--1}" |
| FormatInvalid.cs:33:23:33:30 | "{0:{}}" | semmle.label | "{0:{}}" |
| FormatInvalid.cs:36:23:36:26 | "%d" | semmle.label | "%d" |
| FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | semmle.label | "{{0}-{1}}" |
| FormatInvalid.cs:42:23:42:28 | "{0}}" | semmle.label | "{0}}" |
| FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | semmle.label | "{foo{0}}" |
| FormatInvalid.cs:48:23:48:31 | "{{sdc}}" | semmle.label | "{{sdc}}" |
| FormatInvalid.cs:51:23:51:25 | "}" | semmle.label | "}" |
| FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | semmle.label | "new {0} ({1} => {{" |
| FormatInvalid.cs:57:23:57:26 | "{{" | semmle.label | "{{" |
| FormatInvalid.cs:58:23:58:30 | "{{{{}}" | semmle.label | "{{{{}}" |
| FormatInvalid.cs:75:23:75:25 | "}" | semmle.label | "}" |
| FormatInvalid.cs:76:23:76:25 | "}" | semmle.label | "}" |
| FormatInvalid.cs:77:27:77:29 | "}" | semmle.label | "}" |
| FormatInvalid.cs:78:23:78:25 | "}" | semmle.label | "}" |
| FormatInvalid.cs:79:23:79:25 | "}" | semmle.label | "}" |
| FormatInvalid.cs:80:23:80:25 | "}" | semmle.label | "}" |
| FormatInvalid.cs:82:25:82:27 | "}" | semmle.label | "}" |
| FormatInvalid.cs:83:25:83:27 | "}" | semmle.label | "}" |
| FormatInvalid.cs:84:29:84:31 | "}" | semmle.label | "}" |
| FormatInvalid.cs:85:25:85:27 | "}" | semmle.label | "}" |
| FormatInvalid.cs:86:25:86:27 | "}" | semmle.label | "}" |
| FormatInvalid.cs:87:25:87:27 | "}" | semmle.label | "}" |
| FormatInvalid.cs:89:27:89:29 | "}" | semmle.label | "}" |
| FormatInvalid.cs:90:27:90:29 | "}" | semmle.label | "}" |
| FormatInvalid.cs:91:27:91:29 | "}" | semmle.label | "}" |
| FormatInvalid.cs:92:27:92:29 | "}" | semmle.label | "}" |
| FormatInvalid.cs:93:27:93:29 | "}" | semmle.label | "}" |
| FormatInvalid.cs:95:22:95:24 | "}" | semmle.label | "}" |
| FormatInvalid.cs:96:22:96:24 | "}" | semmle.label | "}" |
| FormatInvalid.cs:97:22:97:24 | "}" | semmle.label | "}" |
| FormatInvalid.cs:98:22:98:24 | "}" | semmle.label | "}" |
| FormatInvalid.cs:99:22:99:24 | "}" | semmle.label | "}" |
| FormatInvalid.cs:101:44:101:46 | "}" | semmle.label | "}" |
| FormatInvalid.cs:102:45:102:47 | "}" | semmle.label | "}" |
| FormatInvalid.cs:103:51:103:53 | "}" | semmle.label | "}" |
| FormatInvalid.cs:104:47:104:49 | "}" | semmle.label | "}" |
| FormatInvalid.cs:105:29:105:31 | "}" | semmle.label | "}" |
| FormatInvalid.cs:107:23:107:25 | "}" | semmle.label | "}" |
| FormatInvalid.cs:108:23:108:25 | "}" | semmle.label | "}" |
| FormatInvalid.cs:109:23:109:25 | "}" | semmle.label | "}" |
| FormatInvalid.cs:110:23:110:25 | "}" | semmle.label | "}" |
| FormatInvalid.cs:115:56:115:58 | "}" | semmle.label | "}" |
| FormatInvalid.cs:116:18:116:20 | "}" | semmle.label | "}" |
| FormatInvalid.cs:117:40:117:42 | "}" | semmle.label | "}" |
| FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | semmle.label | "class {0} { }" |
| FormatInvalidGood.cs:7:30:7:46 | "class {0} {{ }}" | semmle.label | "class {0} {{ }}" |
edges
#select
| FormatInvalid.cs:27:24:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:27:9:27:32 | call to method Format | this |
| FormatInvalid.cs:30:24:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:30:9:30:35 | call to method Format | this |
| FormatInvalid.cs:33:24:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:33:9:33:34 | call to method Format | this |
| FormatInvalid.cs:39:27:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:39:9:39:40 | call to method Format | this |
| FormatInvalid.cs:42:27:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:42:9:42:35 | call to method Format | this |
| FormatInvalid.cs:45:24:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:45:9:45:36 | call to method Format | this |
| FormatInvalid.cs:51:24:51:25 | "}" | FormatInvalid.cs:51:23:51:25 | "}" | FormatInvalid.cs:51:23:51:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:51:9:51:29 | call to method Format | this |
| FormatInvalid.cs:75:24:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:75:9:75:29 | call to method Format | this |
| FormatInvalid.cs:76:24:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:30 | call to method Format | this |
| FormatInvalid.cs:77:28:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:34 | call to method Format | this |
| FormatInvalid.cs:78:24:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:32 | call to method Format | this |
| FormatInvalid.cs:79:24:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:35 | call to method Format | this |
| FormatInvalid.cs:80:24:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:38 | call to method Format | this |
| FormatInvalid.cs:82:26:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this |
| FormatInvalid.cs:83:26:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this |
| FormatInvalid.cs:84:30:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this |
| FormatInvalid.cs:85:26:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this |
| FormatInvalid.cs:86:26:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this |
| FormatInvalid.cs:87:26:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this |
| FormatInvalid.cs:89:28:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this |
| FormatInvalid.cs:90:28:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this |
| FormatInvalid.cs:91:28:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this |
| FormatInvalid.cs:92:28:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this |
| FormatInvalid.cs:93:28:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this |
| FormatInvalid.cs:95:23:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this |
| FormatInvalid.cs:96:23:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this |
| FormatInvalid.cs:97:23:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this |
| FormatInvalid.cs:98:23:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this |
| FormatInvalid.cs:99:23:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this |
| FormatInvalid.cs:101:45:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this |
| FormatInvalid.cs:102:46:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this |
| FormatInvalid.cs:103:52:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this |
| FormatInvalid.cs:104:48:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this |
| FormatInvalid.cs:105:30:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this |
| FormatInvalid.cs:107:24:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:107:9:107:29 | call to method Write | this |
| FormatInvalid.cs:108:24:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:108:9:108:32 | call to method Write | this |
| FormatInvalid.cs:109:24:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:109:9:109:35 | call to method Write | this |
| FormatInvalid.cs:110:24:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:110:9:110:38 | call to method Write | this |
| FormatInvalid.cs:115:57:115:58 | "}" | FormatInvalid.cs:115:56:115:58 | "}" | FormatInvalid.cs:115:56:115:58 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:115:9:115:63 | call to method Assert | this |
| FormatInvalid.cs:116:19:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:116:9:116:24 | call to method Write | this |
| FormatInvalid.cs:117:41:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:117:9:117:47 | call to method Print | this |
| FormatInvalidBad.cs:7:41:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | Invalid format string used in $@ formatting call. | FormatInvalidBad.cs:7:16:7:45 | call to method Format | this |

View File

@@ -1,6 +1,22 @@
| FormatMissingArgument.cs:11:9:11:31 | call to method Format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this |
| FormatMissingArgument.cs:14:9:14:38 | call to method Format | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this |
| FormatMissingArgument.cs:14:9:14:38 | call to method Format | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this |
| FormatMissingArgument.cs:28:9:28:32 | call to method Format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this |
| FormatMissingArgumentBad.cs:7:9:7:49 | call to method WriteLine | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this |
| FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this |
nodes
| FormatMissingArgument.cs:8:23:8:27 | "{0}" | semmle.label | "{0}" |
| FormatMissingArgument.cs:11:23:11:27 | "{1}" | semmle.label | "{1}" |
| FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | semmle.label | "{2} {3}" |
| FormatMissingArgument.cs:17:23:17:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" |
| FormatMissingArgument.cs:20:23:20:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" |
| FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | semmle.label | "{1}" : String |
| FormatMissingArgument.cs:25:24:25:29 | format : String | semmle.label | format : String |
| FormatMissingArgument.cs:28:23:28:28 | access to parameter format | semmle.label | access to parameter format |
| FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" |
| FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | semmle.label | "Hello {1} {2}" |
| FormatMissingArgumentGood.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" |
edges
| FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:25:24:25:29 | format : String |
| FormatMissingArgument.cs:25:24:25:29 | format : String | FormatMissingArgument.cs:28:23:28:28 | access to parameter format |
#select
| FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this |
| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this |
| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this |
| FormatMissingArgument.cs:28:9:28:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:28:23:28:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this |
| FormatMissingArgumentBad.cs:7:9:7:49 | call to method WriteLine | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this |
| FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this |

View File

@@ -1,13 +1,31 @@
| FormatUnusedArgument.cs:11:9:11:29 | call to method Format | The $@ ignores $@. | FormatUnusedArgument.cs:11:23:11:25 | "X" | format string | FormatUnusedArgument.cs:11:28:11:28 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:14:9:14:34 | call to method Format | The $@ ignores $@. | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | format string | FormatUnusedArgument.cs:14:33:14:33 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:17:9:17:38 | call to method Format | The $@ ignores $@. | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | format string | FormatUnusedArgument.cs:17:37:17:37 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:20:9:20:38 | call to method Format | The $@ ignores $@. | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | format string | FormatUnusedArgument.cs:20:34:20:34 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:34:23:34 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:37:23:37 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:40:23:40 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:26:9:26:35 | call to method Format | The $@ ignores $@. | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | format string | FormatUnusedArgument.cs:26:34:26:34 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:38:9:38:33 | call to method Format | The $@ ignores $@. | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | format string | FormatUnusedArgument.cs:38:32:38:32 | (...) ... | this supplied value |
| FormatUnusedArgumentBad.cs:7:9:7:71 | call to method WriteLine | The $@ ignores $@. | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | format string | FormatUnusedArgumentBad.cs:7:61:7:70 | (...) ... | this supplied value |
| FormatUnusedArgumentBad.cs:8:9:8:77 | call to method WriteLine | The $@ ignores $@. | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | format string | FormatUnusedArgumentBad.cs:8:63:8:64 | access to parameter ex | this supplied value |
| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:61:9:62 | access to parameter ex | this supplied value |
| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:65:9:74 | (...) ... | this supplied value |
nodes
| FormatUnusedArgument.cs:8:23:8:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" |
| FormatUnusedArgument.cs:11:23:11:25 | "X" | semmle.label | "X" |
| FormatUnusedArgument.cs:14:23:14:27 | "{0}" | semmle.label | "{0}" |
| FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | semmle.label | "{0} {0}" |
| FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | semmle.label | "{1} {1}" |
| FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | semmle.label | "abcdefg" |
| FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | semmle.label | "{{sdc}}" |
| FormatUnusedArgument.cs:29:23:29:33 | "{{{0:D}}}" | semmle.label | "{{{0:D}}}" |
| FormatUnusedArgument.cs:32:23:32:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" |
| FormatUnusedArgument.cs:35:23:35:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" |
| FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | semmle.label | "{{0}}" |
| FormatUnusedArgument.cs:42:23:42:24 | "" | semmle.label | "" |
| FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | semmle.label | "Error processing file: {0}" |
| FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | semmle.label | "Error processing file: {1} ({1})" |
| FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" |
edges
#select
| FormatUnusedArgument.cs:11:9:11:29 | call to method Format | FormatUnusedArgument.cs:11:23:11:25 | "X" | FormatUnusedArgument.cs:11:23:11:25 | "X" | The $@ ignores $@. | FormatUnusedArgument.cs:11:23:11:25 | "X" | format string | FormatUnusedArgument.cs:11:28:11:28 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:14:9:14:34 | call to method Format | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | The $@ ignores $@. | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | format string | FormatUnusedArgument.cs:14:33:14:33 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:17:9:17:38 | call to method Format | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | The $@ ignores $@. | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | format string | FormatUnusedArgument.cs:17:37:17:37 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:20:9:20:38 | call to method Format | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | The $@ ignores $@. | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | format string | FormatUnusedArgument.cs:20:34:20:34 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:34:23:34 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:37:23:37 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:40:23:40 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:26:9:26:35 | call to method Format | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | The $@ ignores $@. | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | format string | FormatUnusedArgument.cs:26:34:26:34 | (...) ... | this supplied value |
| FormatUnusedArgument.cs:38:9:38:33 | call to method Format | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | The $@ ignores $@. | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | format string | FormatUnusedArgument.cs:38:32:38:32 | (...) ... | this supplied value |
| FormatUnusedArgumentBad.cs:7:9:7:71 | call to method WriteLine | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | format string | FormatUnusedArgumentBad.cs:7:61:7:70 | (...) ... | this supplied value |
| FormatUnusedArgumentBad.cs:8:9:8:77 | call to method WriteLine | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | format string | FormatUnusedArgumentBad.cs:8:63:8:64 | access to parameter ex | this supplied value |
| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:61:9:62 | access to parameter ex | this supplied value |
| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:65:9:74 | (...) ... | this supplied value |

View File

@@ -579,6 +579,8 @@ private module ControlFlowGraphImpl {
n instanceof Stmt and
not n instanceof PostOrderNode and
not n instanceof SynchronizedStmt
or
result = n and n instanceof SwitchExpr
}
/**

View File

@@ -1051,6 +1051,18 @@ class MemberRefExpr extends FunctionalExpr, @memberref {
override string toString() { result = "...::..." }
}
/** A conditional expression or a `switch` expression. */
class ChooseExpr extends Expr {
ChooseExpr() { this instanceof ConditionalExpr or this instanceof SwitchExpr }
/** Gets a result expression of this `switch` or conditional expression. */
Expr getAResultExpr() {
result = this.(ConditionalExpr).getTrueExpr() or
result = this.(ConditionalExpr).getFalseExpr() or
result = this.(SwitchExpr).getAResult()
}
}
/**
* A conditional expression of the form `a ? b : c`, where `a` is the condition,
* `b` is the expression that is evaluated if the condition evaluates to `true`,

View File

@@ -248,8 +248,7 @@ private predicate formatStringFragment(Expr fmt) {
e.(VarAccess).getVariable().getAnAssignedValue() = fmt or
e.(AddExpr).getLeftOperand() = fmt or
e.(AddExpr).getRightOperand() = fmt or
e.(ConditionalExpr).getTrueExpr() = fmt or
e.(ConditionalExpr).getFalseExpr() = fmt
e.(ChooseExpr).getAResultExpr() = fmt
)
}
@@ -293,9 +292,7 @@ private predicate formatStringValue(Expr e, string fmtvalue) {
fmtvalue = left + right
)
or
formatStringValue(e.(ConditionalExpr).getTrueExpr(), fmtvalue)
or
formatStringValue(e.(ConditionalExpr).getFalseExpr(), fmtvalue)
formatStringValue(e.(ChooseExpr).getAResultExpr(), fmtvalue)
or
exists(Method getprop, MethodAccess ma, string prop |
e = ma and

View File

@@ -213,7 +213,7 @@ private predicate hasPossibleUnknownValue(SsaVariable v) {
/**
* Gets a sub-expression of `e` whose value can flow to `e` through
* `ConditionalExpr`s. Parentheses are also removed.
* `ConditionalExpr`s.
*/
private Expr possibleValue(Expr e) {
result = possibleValue(e.(ConditionalExpr).getTrueExpr())

View File

@@ -10,8 +10,7 @@ private import RangeAnalysis
/** Gets an expression that might have the value `i`. */
private Expr exprWithIntValue(int i) {
result.(ConstantIntegerExpr).getIntValue() = i or
result.(ConditionalExpr).getTrueExpr() = exprWithIntValue(i) or
result.(ConditionalExpr).getFalseExpr() = exprWithIntValue(i)
result.(ChooseExpr).getAResultExpr() = exprWithIntValue(i)
}
/**

View File

@@ -45,8 +45,7 @@ private import semmle.code.java.frameworks.Assertions
/** Gets an expression that may be `null`. */
Expr nullExpr() {
result instanceof NullLiteral or
result.(ConditionalExpr).getTrueExpr() = nullExpr() or
result.(ConditionalExpr).getFalseExpr() = nullExpr() or
result.(ChooseExpr).getAResultExpr() = nullExpr() or
result.(AssignExpr).getSource() = nullExpr() or
result.(CastExpr).getExpr() = nullExpr()
}
@@ -81,9 +80,7 @@ private predicate unboxed(Expr e) {
or
exists(UnaryExpr un | un.getExpr() = e)
or
exists(ConditionalExpr cond | cond.getType() instanceof PrimitiveType |
cond.getTrueExpr() = e or cond.getFalseExpr() = e
)
exists(ChooseExpr cond | cond.getType() instanceof PrimitiveType | cond.getAResultExpr() = e)
or
exists(ConditionNode cond | cond.getCondition() = e)
or

View File

@@ -552,9 +552,7 @@ private Sign exprSign(Expr e) {
result = s1.urshift(s2)
)
or
result = exprSign(e.(ConditionalExpr).getTrueExpr())
or
result = exprSign(e.(ConditionalExpr).getFalseExpr())
result = exprSign(e.(ChooseExpr).getAResultExpr())
or
result = exprSign(e.(CastExpr).getExpr())
)

View File

@@ -72,9 +72,7 @@ private predicate privateParamArg(Parameter p, Argument arg) {
* necessarily functionally determined by `n2`.
*/
private predicate joinStep0(TypeFlowNode n1, TypeFlowNode n2) {
n2.asExpr().(ConditionalExpr).getTrueExpr() = n1.asExpr()
or
n2.asExpr().(ConditionalExpr).getFalseExpr() = n1.asExpr()
n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr()
or
exists(Field f, Expr e |
f = n2.asField() and
@@ -226,9 +224,8 @@ private predicate upcastCand(TypeFlowNode n, RefType t, RefType t1, RefType t2)
or
exists(Parameter p | privateParamArg(p, n.asExpr()) and t2 = p.getType().getErasure())
or
exists(ConditionalExpr cond |
cond.getTrueExpr() = n.asExpr() or cond.getFalseExpr() = n.asExpr()
|
exists(ChooseExpr cond |
cond.getAResultExpr() = n.asExpr() and
t2 = cond.getType().getErasure()
)
)

View File

@@ -397,9 +397,7 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
or
node2.asExpr().(CastExpr).getExpr() = node1.asExpr()
or
node2.asExpr().(ConditionalExpr).getTrueExpr() = node1.asExpr()
or
node2.asExpr().(ConditionalExpr).getFalseExpr() = node1.asExpr()
node2.asExpr().(ChooseExpr).getAResultExpr() = node1.asExpr()
or
node2.asExpr().(AssignExpr).getSource() = node1.asExpr()
}

View File

@@ -296,6 +296,7 @@ private predicate taintPreservingQualifierToMethod(Method m) {
(
m.getName() = "concat" or
m.getName() = "endsWith" or
m.getName() = "formatted" or
m.getName() = "getBytes" or
m.getName() = "split" or
m.getName() = "substring" or
@@ -395,7 +396,7 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
*/
private predicate taintPreservingArgumentToMethod(Method method) {
method.getDeclaringType() instanceof TypeString and
(method.hasName("format") or method.hasName("join"))
(method.hasName("format") or method.hasName("formatted") or method.hasName("join"))
}
/**

View File

@@ -202,9 +202,7 @@ private predicate flowStep(RelevantNode n1, RelevantNode n2) {
or
n2.asExpr().(CastExpr).getExpr() = n1.asExpr()
or
n2.asExpr().(ConditionalExpr).getTrueExpr() = n1.asExpr()
or
n2.asExpr().(ConditionalExpr).getFalseExpr() = n1.asExpr()
n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr()
or
n2.asExpr().(AssignExpr).getSource() = n1.asExpr()
or

View File

@@ -100,9 +100,7 @@ private predicate step(Node n1, Node n2) {
or
n2.asExpr().(CastExpr).getExpr() = n1.asExpr()
or
n2.asExpr().(ConditionalExpr).getTrueExpr() = n1.asExpr()
or
n2.asExpr().(ConditionalExpr).getFalseExpr() = n1.asExpr()
n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr()
or
n2.asExpr().(AssignExpr).getSource() = n1.asExpr()
or

View File

@@ -0,0 +1,25 @@
class TestSwitchExpr {
Object source() { return new Object(); }
void sink(Object o) { }
void test(String s) {
Object x1 = source();
Object x2 = switch (s) {
case "a", "b", ("a" + "b") -> null;
default -> x1;
};
Object x3 = switch (s) {
case "c", "d" -> { yield x2; }
default -> throw new RuntimeException();
};
Object x4 = switch (s) {
case "a", "b":
case "c", "d", ("c" + "d"):
yield x3;
default:
throw new RuntimeException();
};
sink(x4);
}
}

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -source 14 -target 14

View File

@@ -0,0 +1,9 @@
| TestSwitchExpr.java:4:15:4:22 | o |
| TestSwitchExpr.java:7:21:7:28 | source(...) |
| TestSwitchExpr.java:8:21:8:30 | switch (...) |
| TestSwitchExpr.java:10:24:10:25 | x1 |
| TestSwitchExpr.java:12:21:12:30 | switch (...) |
| TestSwitchExpr.java:13:38:13:39 | x2 |
| TestSwitchExpr.java:16:21:16:30 | switch (...) |
| TestSwitchExpr.java:19:23:19:24 | x3 |
| TestSwitchExpr.java:23:14:23:15 | x4 |

View File

@@ -0,0 +1,15 @@
import java
import semmle.code.java.dataflow.DataFlow
import DataFlow
class Conf extends Configuration {
Conf() { this = "qqconf" }
override predicate isSource(Node n) { n.asExpr().(MethodAccess).getMethod().hasName("source") }
override predicate isSink(Node n) { any() }
}
from Conf c, Node sink
where c.hasFlow(_, sink)
select sink

View File

@@ -27,11 +27,10 @@ class DangerousScheme extends string {
/** Returns a node that refers to the scheme of `url`. */
DataFlow::SourceNode schemeOf(DataFlow::Node url) {
// url.split(":")[0]
exists(DataFlow::MethodCallNode split |
split.getMethodName() = "split" and
split.getArgument(0).getStringValue() = ":" and
result = split.getAPropertyRead("0") and
url = split.getReceiver()
exists(StringSplitCall split |
split.getSeparator() = ":" and
result = split.getASubstringRead(0) and
url = split.getBaseString()
)
or
// url.getScheme(), url.getProtocol(), getScheme(url), getProtocol(url)

View File

@@ -1,4 +1,4 @@
$("button").click(function () {
var target = this.attr("data-target");
var target = $(this).attr("data-target");
$(target).hide();
});

View File

@@ -1,4 +1,4 @@
$("button").click(function () {
var target = this.attr("data-target");
$.find(target).hide();
var target = $(this).attr("data-target");
$.find(target).hide();
});

View File

@@ -1,18 +1,21 @@
const pg = require('pg');
const pool = new pg.Pool(config);
const app = require("express")(),
pg = require("pg"),
pool = new pg.Pool(config);
function handler(req, res) {
app.get("search", function handler(req, res) {
// BAD: the category might have SQL special characters in it
var query1 = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ req.params.category + "' ORDER BY PRICE";
var query1 =
"SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" +
req.params.category +
"' ORDER BY PRICE";
pool.query(query1, [], function(err, results) {
// process results
});
// GOOD: use parameters
var query2 = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=$1"
+ " ORDER BY PRICE";
var query2 =
"SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=$1" + " ORDER BY PRICE";
pool.query(query2, [req.params.category], function(err, results) {
// process results
// process results
});
}
});

View File

@@ -0,0 +1,99 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Sanitizing untrusted input for HTML meta-characters is an
important technique for preventing cross-site scripting attacks. But
even a sanitized input can be dangerous to use if it is modified
further before a browser treats it as HTML.
A seemingly innocent transformation that expands a
self-closing HTML tag from <code>&lt;div attr="{sanitized}"/&gt;</code>
to <code>&lt;div attr="{sanitized}"&gt;&lt;/div&gt;</code> may
in fact cause cross-site scripting vulnerabilities.
</p>
</overview>
<recommendation>
<p>
Use a well-tested sanitization library if at all
possible, and avoid modifying sanitized values further before treating
them as HTML.
</p>
</recommendation>
<example>
<p>
The following function transforms a self-closing HTML tag
to a pair of open/close tags. It does so for all non-<code>img</code>
and non-<code>area</code> tags, by using a regular expression with two
capture groups. The first capture group corresponds to the name of the
tag, and the second capture group to the content of the tag.
</p>
<sample src="examples/UnsafeHtmlExpansion.js" />
<p>
While it is generally known regular expressions are
ill-suited for parsing HTML, variants of this particular transformation
pattern have long been considered safe.
</p>
<p>
However, the function is not safe. As an example, consider
the following string:
</p>
<sample src="examples/UnsafeHtmlExpansion-original.html" />
<p>
When the above function transforms the string, it becomes
a string that results in an alert when a browser treats it as HTML.
</p>
<sample src="examples/UnsafeHtmlExpansion-transformed.html" />
</example>
<references>
<li>jQuery:
<a href="https://blog.jquery.com/2020/04/10/jquery-3-5-0-released/">Security fixes in jQuery 3.5.0</a>
</li>
<li>
OWASP:
<a href="https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html">DOM based
XSS Prevention Cheat Sheet</a>.
</li>
<li>
OWASP:
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html">XSS
(Cross Site Scripting) Prevention Cheat Sheet</a>.
</li>
<li>
OWASP
<a href="https://owasp.org/www-community/Types_of_Cross-Site_Scripting">Types of Cross-Site</a>.
</li>
<li>
Wikipedia: <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">Cross-site scripting</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,58 @@
/**
* @name Unsafe expansion of self-closing HTML tag
* @description Using regular expressions to expand self-closing HTML
* tags may lead to cross-site scripting vulnerabilities.
* @kind problem
* @problem.severity warning
* @precision very-high
* @id js/unsafe-html-expansion
* @tags correctness
* security
* external/cwe/cwe-079
* external/cwe/cwe-116
*/
import javascript
/**
* A regular expression that captures the name and content of a
* self-closing HTML tag such as `<div id='foo'/>`.
*/
class SelfClosingTagRecognizer extends DataFlow::RegExpCreationNode {
SelfClosingTagRecognizer() {
exists(RegExpSequence seq, RegExpGroup name, RegExpGroup content |
// `/.../g`
RegExp::isGlobal(this.getFlags()) and
this.getRoot() = seq.getRootTerm() and
// `/<.../`
seq.getChild(0).getConstantValue() = "<" and
// `/...\/>/`
seq.getLastChild().getPredecessor().getConstantValue() = "/" and
seq.getLastChild().getConstantValue() = ">" and
// `/...((...)...).../`
seq.getAChild() = content and
content.getNumber() = 1 and
name.getNumber() = 2 and
name = content.getChild(0).(RegExpSequence).getChild(0) and
// `/...(([a-z]+)...).../` or `/...(([a-z][...]*)...).../`
exists(RegExpQuantifier quant | name.getAChild*() = quant |
quant instanceof RegExpStar or
quant instanceof RegExpPlus
) and
// `/...((...)[^>]*).../`
exists(RegExpCharacterClass lazy |
name.getSuccessor().(RegExpStar).getChild(0) = lazy and
lazy.isInverted() and
lazy.getAChild().getConstantValue() = ">"
)
)
}
}
from SelfClosingTagRecognizer regexp, StringReplaceCall replace
where
regexp.getAReference().flowsTo(replace.getArgument(0)) and
replace.getRawReplacement().mayHaveStringValue("<$1></$2>")
select replace,
"This self-closing HTML tag expansion invalidates prior sanitization as $@ may match part of an attribute value.",
regexp, "this regular expression"

View File

@@ -0,0 +1,3 @@
<div alt="
<x" title="/>
<img src=url404 onerror=alert(1)>"/>

View File

@@ -0,0 +1,3 @@
<img alt="
<x" title="></x" >
<img src=url404 onerror=alert(1)>"/>

View File

@@ -0,0 +1,4 @@
function expandSelfClosingTags(html) {
var rxhtmlTag = /<(?!img|area)(([a-z][^\w\/>]*)[^>]*)\/>/gi;
return html.replace(rxhtmlTag, "<$1></$2>"); // BAD
}

View File

@@ -1 +1,7 @@
console.log("Unauthorized access attempt by " + user, ip);
const app = require("express")();
app.get("unauthorized", function handler(req, res) {
let user = req.query.user;
let ip = req.connection.remoteAddress;
console.log("Unauthorized access attempt by " + user, ip);
});

View File

@@ -1 +1,7 @@
console.log("Unauthorized access attempt by %s", user, ip);
const app = require("express")();
app.get("unauthorized", function handler(req, res) {
let user = req.query.user;
let ip = req.connection.remoteAddress;
console.log("Unauthorized access attempt by %s", user, ip);
});

View File

@@ -1,7 +1,9 @@
const crypto = require('crypto');
var secretText = obj.getSecretText();
const desCipher = crypto.createCipher('des', key);
let desEncrypted = cipher.write(secretText, 'utf8', 'hex'); // BAD: weak encryption
let desEncrypted = desCipher.write(secretText, 'utf8', 'hex'); // BAD: weak encryption
const aesCipher = crypto.createCipher('aes-128', key);
let aesEncrypted = cipher.update(secretText, 'utf8', 'hex'); // GOOD: strong encryption
let aesEncrypted = aesCipher.update(secretText, 'utf8', 'hex'); // GOOD: strong encryption

View File

@@ -1,11 +1,11 @@
var express = require('express')
var cookieParser = require('cookie-parser')
var passport = require('passport')
var app = require("express")(),
cookieParser = require("cookie-parser"),
passport = require("passport");
var app = express()
app.use(cookieParser());
app.use(passport.authorize({ session: true }));
app.use(cookieParser())
app.use(passport.authorize({ session: true }))
app.post('/changeEmail', ..., function (req, res) {
})
app.post("/changeEmail", function(req, res) {
let newEmail = req.cookies["newEmail"];
// ...
});

View File

@@ -1,13 +1,12 @@
var express = require('express')
var cookieParser = require('cookie-parser')
var passport = require('passport')
var csrf = require('csurf')
var app = require("express")(),
cookieParser = require("cookie-parser"),
passport = require("passport"),
csrf = require("csurf");
var app = express()
app.use(cookieParser())
app.use(passport.authorize({ session: true }))
app.use(csrf({ cookie:true }))
app.post('/changeEmail', ..., function (req, res) {
})
app.use(cookieParser());
app.use(passport.authorize({ session: true }));
app.use(csrf({ cookie: true }));
app.post("/changeEmail", function(req, res) {
let newEmail = req.cookies["newEmail"];
// ...
});

View File

@@ -21,11 +21,10 @@ import semmle.javascript.DynamicPropertyAccess
*
* We restrict this to parameter nodes to focus on "deep assignment" functions.
*/
class SplitCall extends MethodCallNode {
class SplitCall extends StringSplitCall {
SplitCall() {
getMethodName() = "split" and
getArgument(0).mayHaveStringValue(".") and
getReceiver().getALocalSource() instanceof ParameterNode
getSeparator() = "." and
getBaseString().getALocalSource() instanceof ParameterNode
}
}

View File

@@ -1,6 +1,7 @@
const jsyaml = require("js-yaml");
const app = require("express")(),
jsyaml = require("js-yaml");
function requestHandler(req, res) {
app.get("load", function(req, res) {
let data = jsyaml.load(req.params.data);
// ...
}
});

View File

@@ -1,6 +1,7 @@
const jsyaml = require("js-yaml");
const app = require("express")(),
jsyaml = require("js-yaml");
function requestHandler(req, res) {
app.get("load", function(req, res) {
let data = jsyaml.safeLoad(req.params.data);
// ...
}
});

View File

@@ -1,3 +1,5 @@
const app = require("express")();
app.get('/some/path', function(req, res) {
// BAD: a request parameter is incorporated without validation into a URL redirect
res.redirect(req.param("target"));

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