mirror of
https://github.com/github/codeql.git
synced 2026-04-22 07:15:15 +02:00
Merge branch 'master' of https://github.com/github/codeql into pr/erik-krogh/3478
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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() }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -14,3 +14,4 @@ private import implementations.Strdup
|
||||
private import implementations.Strftime
|
||||
private import implementations.StdString
|
||||
private import implementations.Swap
|
||||
private import implementations.GetDelim
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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. |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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), ", ")
|
||||
|
||||
@@ -39,3 +39,6 @@ public:
|
||||
MyClass(MyClass &&from);
|
||||
operator int();
|
||||
};
|
||||
|
||||
void h(int x);
|
||||
void h(int y);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
2100
cpp/upgrades/2074f1cc7a3659ad555465a8025a8f2b7687896b/old.dbscheme
Normal file
2100
cpp/upgrades/2074f1cc7a3659ad555465a8025a8f2b7687896b/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add union types for casts and accesses
|
||||
compatibility: full
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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> |
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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`,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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"))
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
1
java/ql/test/library-tests/dataflow/switchexpr/options
Normal file
1
java/ql/test/library-tests/dataflow/switchexpr/options
Normal file
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -source 14 -target 14
|
||||
@@ -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 |
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
$("button").click(function () {
|
||||
var target = this.attr("data-target");
|
||||
var target = $(this).attr("data-target");
|
||||
$(target).hide();
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
99
javascript/ql/src/Security/CWE-116/UnsafeHtmlExpansion.qhelp
Normal file
99
javascript/ql/src/Security/CWE-116/UnsafeHtmlExpansion.qhelp
Normal 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><div attr="{sanitized}"/></code>
|
||||
to <code><div attr="{sanitized}"></div></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>
|
||||
58
javascript/ql/src/Security/CWE-116/UnsafeHtmlExpansion.ql
Normal file
58
javascript/ql/src/Security/CWE-116/UnsafeHtmlExpansion.ql
Normal 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"
|
||||
@@ -0,0 +1,3 @@
|
||||
<div alt="
|
||||
<x" title="/>
|
||||
<img src=url404 onerror=alert(1)>"/>
|
||||
@@ -0,0 +1,3 @@
|
||||
<img alt="
|
||||
<x" title="></x" >
|
||||
<img src=url404 onerror=alert(1)>"/>
|
||||
@@ -0,0 +1,4 @@
|
||||
function expandSelfClosingTags(html) {
|
||||
var rxhtmlTag = /<(?!img|area)(([a-z][^\w\/>]*)[^>]*)\/>/gi;
|
||||
return html.replace(rxhtmlTag, "<$1></$2>"); // BAD
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"];
|
||||
// ...
|
||||
});
|
||||
|
||||
@@ -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"];
|
||||
// ...
|
||||
});
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
// ...
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
// ...
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user