Merge branch 'main' into atorralba/fix-local-and-remote-flow-tests

This commit is contained in:
Tony Torralba
2021-10-18 08:52:37 +02:00
committed by GitHub
507 changed files with 21855 additions and 11474 deletions

View File

@@ -367,6 +367,7 @@
],
"Inline Test Expectations": [
"cpp/ql/test/TestUtilities/InlineExpectationsTest.qll",
"csharp/ql/test/TestUtilities/InlineExpectationsTest.qll",
"java/ql/test/TestUtilities/InlineExpectationsTest.qll",
"python/ql/test/TestUtilities/InlineExpectationsTest.qll"
],
@@ -461,5 +462,12 @@
"ReDoS Polynomial Python/JS": [
"javascript/ql/lib/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
"python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll"
],
"CodeQL Tutorial": [
"cpp/ql/lib/tutorial.qll",
"csharp/ql/lib/tutorial.qll",
"java/ql/lib/tutorial.qll",
"javascript/ql/lib/tutorial.qll",
"python/ql/lib/tutorial.qll"
]
}

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Several improvements made to the `NullTermination.qll` library and the 'Potential improper null termination' (cpp/improper-null-termination). These changes reduce the number of false positive results for this query and related query 'User-controlled data may not be null terminated' (cpp/user-controlled-null-termination-tainted).

View File

@@ -0,0 +1,3 @@
codescanning
* Problems with extraction that in most cases won't break the analysis in a significant way are now reported as warnings rather than errors.
* The failed extractor invocations query now has severity `error`.

View File

@@ -275,9 +275,8 @@ class Declaration extends Locatable, @declaration {
* `getTemplateArgumentKind(0)`.
*/
final Locatable getTemplateArgumentKind(int index) {
if exists(getTemplateArgumentValue(index))
then result = getTemplateArgumentType(index)
else none()
exists(getTemplateArgumentValue(index)) and
result = getTemplateArgumentType(index)
}
/** Gets the number of template arguments for this declaration. */

View File

@@ -1650,7 +1650,6 @@ class RoutineType extends Type, @routinetype {
i = 0 and result = "" and not exists(this.getAParameterType())
or
(
exists(this.getParameterType(i)) and
if i < max(int j | exists(this.getParameterType(j)))
then
// Not the last one

View File

@@ -108,7 +108,7 @@ class XMLParent extends @xmlparent {
}
/** Gets the text value contained in this XML parent. */
string getTextValue() { result = allCharactersString() }
string getTextValue() { result = this.allCharactersString() }
/** Gets a printable representation of this XML parent. */
string toString() { result = this.getName() }
@@ -119,7 +119,7 @@ class XMLFile extends XMLParent, File {
XMLFile() { xmlEncoding(this, _) }
/** Gets a printable representation of this XML file. */
override string toString() { result = getName() }
override string toString() { result = this.getName() }
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
@@ -129,14 +129,14 @@ class XMLFile extends XMLParent, File {
*
* Gets the path of this XML file.
*/
deprecated string getPath() { result = getAbsolutePath() }
deprecated string getPath() { result = this.getAbsolutePath() }
/**
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
*
* Gets the path of the folder that contains this XML file.
*/
deprecated string getFolder() { result = getParentContainer().getAbsolutePath() }
deprecated string getFolder() { result = this.getParentContainer().getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }
@@ -200,7 +200,7 @@ class XMLDTD extends XMLLocatable, @xmldtd {
*/
class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
/** Holds if this XML element has the given `name`. */
predicate hasName(string name) { name = getName() }
predicate hasName(string name) { name = this.getName() }
/** Gets the name of this XML element. */
override string getName() { xmlElements(this, result, _, _, _) }
@@ -239,7 +239,7 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }
/** Gets a printable representation of this XML element. */
override string toString() { result = getName() }
override string toString() { result = this.getName() }
}
/**

View File

@@ -1,6 +1,7 @@
import cpp
private import semmle.code.cpp.models.interfaces.ArrayFunction
private import semmle.code.cpp.models.implementations.Strcat
import semmle.code.cpp.dataflow.DataFlow
private predicate mayAddNullTerminatorHelper(Expr e, VariableAccess va, Expr e0) {
exists(StackVariable v0, Expr val |
@@ -45,22 +46,28 @@ predicate mayAddNullTerminator(Expr e, VariableAccess va) {
ae.getRValue().getAChild*() = va
)
or
// Function call: library function, varargs function, function
// containing assembler code, or function where the relevant
// parameter is potentially added a null terminator.
// Function calls...
exists(Call c, Function f, int i |
e = c and
f = c.getTarget() and
not functionArgumentMustBeNullTerminated(f, i) and
c.getAnArgumentSubExpr(i) = va
|
not f.hasEntryPoint() and not functionArgumentMustBeNullTerminated(f, i)
// library function
not f.hasEntryPoint()
or
// function where the relevant parameter is potentially added a null terminator
mayAddNullTerminator(_, f.getParameter(i).getAnAccess())
or
// varargs function
f.isVarargs() and i >= f.getNumberOfParameters()
or
// function containing assembler code
exists(AsmStmt s | s.getEnclosingFunction() = f)
or
// function where the relevant parameter is returned (leaking it to be potentially null terminated elsewhere)
DataFlow::localFlow(DataFlow::parameterNode(f.getParameter(i)),
DataFlow::exprNode(any(ReturnStmt rs).getExpr()))
)
or
// Call without target (e.g., function pointer call)

View File

@@ -344,14 +344,13 @@ private int convertIntToType(int val, IntegralType t) {
then if val = 0 then result = 0 else result = 1
else
if t.isUnsigned()
then if val >= 0 and val.bitShiftRight(t.getSize() * 8) = 0 then result = val else none()
then val >= 0 and val.bitShiftRight(t.getSize() * 8) = 0 and result = val
else
if val >= 0 and val.bitShiftRight(t.getSize() * 8 - 1) = 0
then result = val
else
if (-(val + 1)).bitShiftRight(t.getSize() * 8 - 1) = 0
then result = val
else none()
else (
(-(val + 1)).bitShiftRight(t.getSize() * 8 - 1) = 0 and result = val
)
}
/**

View File

@@ -937,7 +937,7 @@ class CallContextSpecificCall extends CallContextCall, TSpecificCall {
}
override predicate relevantFor(DataFlowCallable callable) {
recordDataFlowCallSite(getCall(), callable)
recordDataFlowCallSite(this.getCall(), callable)
}
override predicate matchesCall(DataFlowCall call) { call = this.getCall() }
@@ -1257,7 +1257,7 @@ abstract class AccessPathFront extends TAccessPathFront {
TypedContent getHead() { this = TFrontHead(result) }
predicate isClearedAt(Node n) { clearsContentCached(n, getHead().getContent()) }
predicate isClearedAt(Node n) { clearsContentCached(n, this.getHead().getContent()) }
}
class AccessPathFrontNil extends AccessPathFront, TFrontNil {

View File

@@ -219,15 +219,13 @@ class DataFlowExpr = Expr;
class DataFlowType = Type;
/** A function call relevant for data flow. */
class DataFlowCall extends Expr {
DataFlowCall() { this instanceof Call }
class DataFlowCall extends Expr instanceof Call {
/**
* Gets the nth argument for this call.
*
* The range of `n` is from `0` to `getNumberOfArguments() - 1`.
*/
Expr getArgument(int n) { result = this.(Call).getArgument(n) }
Expr getArgument(int n) { result = super.getArgument(n) }
/** Gets the data flow node corresponding to this call. */
ExprNode getNode() { result.getExpr() = this }

View File

@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
}
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
isAdditionalTaintStep(node1, node2) or
this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}

View File

@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
}
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
isAdditionalTaintStep(node1, node2) or
this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}

View File

@@ -937,7 +937,7 @@ class CallContextSpecificCall extends CallContextCall, TSpecificCall {
}
override predicate relevantFor(DataFlowCallable callable) {
recordDataFlowCallSite(getCall(), callable)
recordDataFlowCallSite(this.getCall(), callable)
}
override predicate matchesCall(DataFlowCall call) { call = this.getCall() }
@@ -1257,7 +1257,7 @@ abstract class AccessPathFront extends TAccessPathFront {
TypedContent getHead() { this = TFrontHead(result) }
predicate isClearedAt(Node n) { clearsContentCached(n, getHead().getContent()) }
predicate isClearedAt(Node n) { clearsContentCached(n, this.getHead().getContent()) }
}
class AccessPathFrontNil extends AccessPathFront, TFrontNil {

View File

@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
}
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
isAdditionalTaintStep(node1, node2) or
this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}

View File

@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
}
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
isAdditionalTaintStep(node1, node2) or
this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}

View File

@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
}
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
isAdditionalTaintStep(node1, node2) or
this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}

View File

@@ -24,7 +24,7 @@ class IRBlockBase extends TIRBlock {
final string toString() { result = getFirstInstruction(this).toString() }
/** Gets the source location of the first non-`Phi` instruction in this block. */
final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
final Language::Location getLocation() { result = this.getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
@@ -39,7 +39,7 @@ class IRBlockBase extends TIRBlock {
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
funcBlock.getEnclosingFunction() = getEnclosingFunction() and
funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
@@ -59,15 +59,15 @@ class IRBlockBase extends TIRBlock {
* Get the `Phi` instructions that appear at the start of this block.
*/
final PhiInstruction getAPhiInstruction() {
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
Construction::getPhiInstructionBlockStart(result) = this.getFirstInstruction()
}
/**
* Gets an instruction in this block. This includes `Phi` instructions.
*/
final Instruction getAnInstruction() {
result = getInstruction(_) or
result = getAPhiInstruction()
result = this.getInstruction(_) or
result = this.getAPhiInstruction()
}
/**
@@ -78,7 +78,9 @@ class IRBlockBase extends TIRBlock {
/**
* Gets the last instruction in this block.
*/
final Instruction getLastInstruction() { result = getInstruction(getInstructionCount() - 1) }
final Instruction getLastInstruction() {
result = this.getInstruction(this.getInstructionCount() - 1)
}
/**
* Gets the number of non-`Phi` instructions in this block.
@@ -149,7 +151,7 @@ class IRBlock extends IRBlockBase {
* Block `A` dominates block `B` if any control flow path from the entry block of the function to
* block `B` must pass through block `A`. A block always dominates itself.
*/
final predicate dominates(IRBlock block) { strictlyDominates(block) or this = block }
final predicate dominates(IRBlock block) { this.strictlyDominates(block) or this = block }
/**
* Gets a block on the dominance frontier of this block.
@@ -159,8 +161,8 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock dominanceFrontier() {
dominates(result.getAPredecessor()) and
not strictlyDominates(result)
this.dominates(result.getAPredecessor()) and
not this.strictlyDominates(result)
}
/**
@@ -189,7 +191,7 @@ class IRBlock extends IRBlockBase {
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
final predicate postDominates(IRBlock block) { this.strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
@@ -199,16 +201,16 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
postDominates(result.getASuccessor()) and
not strictlyPostDominates(result)
this.postDominates(result.getASuccessor()) and
not this.strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
final predicate isReachableFromFunctionEntry() {
this = getEnclosingIRFunction().getEntryBlock() or
getAPredecessor().isReachableFromFunctionEntry()
this = this.getEnclosingIRFunction().getEntryBlock() or
this.getAPredecessor().isReachableFromFunctionEntry()
}
}

View File

@@ -46,12 +46,12 @@ class Operand extends TStageOperand {
/**
* Gets the location of the source code for this operand.
*/
final Language::Location getLocation() { result = getUse().getLocation() }
final Language::Location getLocation() { result = this.getUse().getLocation() }
/**
* Gets the function that contains this operand.
*/
final IRFunction getEnclosingIRFunction() { result = getUse().getEnclosingIRFunction() }
final IRFunction getEnclosingIRFunction() { result = this.getUse().getEnclosingIRFunction() }
/**
* Gets the `Instruction` that consumes this operand.
@@ -74,7 +74,7 @@ class Operand extends TStageOperand {
*/
final Instruction getDef() {
result = this.getAnyDef() and
getDefinitionOverlap() instanceof MustExactlyOverlap
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
@@ -82,7 +82,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = getUse() }
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
@@ -91,7 +91,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = getAnyDef() }
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
@@ -101,7 +101,9 @@ class Operand extends TStageOperand {
/**
* Holds if the result of the definition instruction does not exactly overlap this use.
*/
final predicate isDefinitionInexact() { not getDefinitionOverlap() instanceof MustExactlyOverlap }
final predicate isDefinitionInexact() {
not this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* Gets a prefix to use when dumping the operand in an operand list.
@@ -121,7 +123,7 @@ class Operand extends TStageOperand {
* For example: `this:r3_5`
*/
final string getDumpString() {
result = getDumpLabel() + getInexactSpecifier() + getDefinitionId()
result = this.getDumpLabel() + this.getInexactSpecifier() + this.getDefinitionId()
}
/**
@@ -129,9 +131,9 @@ class Operand extends TStageOperand {
* definition is not modeled in SSA.
*/
private string getDefinitionId() {
result = getAnyDef().getResultId()
result = this.getAnyDef().getResultId()
or
not exists(getAnyDef()) and result = "m?"
not exists(this.getAnyDef()) and result = "m?"
}
/**
@@ -140,7 +142,7 @@ class Operand extends TStageOperand {
* the empty string.
*/
private string getInexactSpecifier() {
if isDefinitionInexact() then result = "~" else result = ""
if this.isDefinitionInexact() then result = "~" else result = ""
}
/**
@@ -155,7 +157,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
Language::LanguageType getLanguageType() { result = getAnyDef().getResultLanguageType() }
Language::LanguageType getLanguageType() { result = this.getAnyDef().getResultLanguageType() }
/**
* Gets the language-neutral type of the value consumed by this operand. This is usually the same
@@ -164,7 +166,7 @@ class Operand extends TStageOperand {
* from the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
final IRType getIRType() { result = getLanguageType().getIRType() }
final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the value consumed by this operand. This is usually the same as the
@@ -173,7 +175,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
final Language::Type getType() { getLanguageType().hasType(result, _) }
final Language::Type getType() { this.getLanguageType().hasType(result, _) }
/**
* Holds if the value consumed by this operand is a glvalue. If this
@@ -182,13 +184,13 @@ class Operand extends TStageOperand {
* not hold, the value of the operand represents a value whose type is
* given by `getType()`.
*/
final predicate isGLValue() { getLanguageType().hasType(_, true) }
final predicate isGLValue() { this.getLanguageType().hasType(_, true) }
/**
* Gets the size of the value consumed by this operand, in bytes. If the operand does not have
* a known constant size, this predicate does not hold.
*/
final int getSize() { result = getLanguageType().getByteSize() }
final int getSize() { result = this.getLanguageType().getByteSize() }
}
/**
@@ -205,7 +207,7 @@ class MemoryOperand extends Operand {
/**
* Gets the kind of memory access performed by the operand.
*/
MemoryAccessKind getMemoryAccess() { result = getUse().getOpcode().getReadMemoryAccess() }
MemoryAccessKind getMemoryAccess() { result = this.getUse().getOpcode().getReadMemoryAccess() }
/**
* Holds if the memory access performed by this operand will not always read from every bit in the
@@ -215,7 +217,7 @@ class MemoryOperand extends Operand {
* conservative estimate of the memory that might actually be accessed at runtime (for example,
* the global side effects of a function call).
*/
predicate hasMayReadMemoryAccess() { getUse().getOpcode().hasMayReadMemoryAccess() }
predicate hasMayReadMemoryAccess() { this.getUse().getOpcode().hasMayReadMemoryAccess() }
/**
* Returns the operand that holds the memory address from which the current operand loads its
@@ -223,8 +225,8 @@ class MemoryOperand extends Operand {
* is `r1`.
*/
final AddressOperand getAddressOperand() {
getMemoryAccess().usesAddressOperand() and
result.getUse() = getUse()
this.getMemoryAccess().usesAddressOperand() and
result.getUse() = this.getUse()
}
}
@@ -294,7 +296,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
final override Overlap getDefinitionOverlap() { this.hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
@@ -449,13 +451,17 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
final override Overlap getDefinitionOverlap() { result = overlap }
final override int getDumpSortOrder() { result = 11 + getPredecessorBlock().getDisplayIndex() }
final override string getDumpLabel() {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
final override int getDumpSortOrder() {
result = 11 + this.getPredecessorBlock().getDisplayIndex()
}
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
final override string getDumpLabel() {
result = "from " + this.getPredecessorBlock().getDisplayIndex().toString() + ":"
}
final override string getDumpId() {
result = this.getPredecessorBlock().getDisplayIndex().toString()
}
/**
* Gets the predecessor block from which this value comes.

View File

@@ -24,7 +24,7 @@ class IRBlockBase extends TIRBlock {
final string toString() { result = getFirstInstruction(this).toString() }
/** Gets the source location of the first non-`Phi` instruction in this block. */
final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
final Language::Location getLocation() { result = this.getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
@@ -39,7 +39,7 @@ class IRBlockBase extends TIRBlock {
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
funcBlock.getEnclosingFunction() = getEnclosingFunction() and
funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
@@ -59,15 +59,15 @@ class IRBlockBase extends TIRBlock {
* Get the `Phi` instructions that appear at the start of this block.
*/
final PhiInstruction getAPhiInstruction() {
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
Construction::getPhiInstructionBlockStart(result) = this.getFirstInstruction()
}
/**
* Gets an instruction in this block. This includes `Phi` instructions.
*/
final Instruction getAnInstruction() {
result = getInstruction(_) or
result = getAPhiInstruction()
result = this.getInstruction(_) or
result = this.getAPhiInstruction()
}
/**
@@ -78,7 +78,9 @@ class IRBlockBase extends TIRBlock {
/**
* Gets the last instruction in this block.
*/
final Instruction getLastInstruction() { result = getInstruction(getInstructionCount() - 1) }
final Instruction getLastInstruction() {
result = this.getInstruction(this.getInstructionCount() - 1)
}
/**
* Gets the number of non-`Phi` instructions in this block.
@@ -149,7 +151,7 @@ class IRBlock extends IRBlockBase {
* Block `A` dominates block `B` if any control flow path from the entry block of the function to
* block `B` must pass through block `A`. A block always dominates itself.
*/
final predicate dominates(IRBlock block) { strictlyDominates(block) or this = block }
final predicate dominates(IRBlock block) { this.strictlyDominates(block) or this = block }
/**
* Gets a block on the dominance frontier of this block.
@@ -159,8 +161,8 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock dominanceFrontier() {
dominates(result.getAPredecessor()) and
not strictlyDominates(result)
this.dominates(result.getAPredecessor()) and
not this.strictlyDominates(result)
}
/**
@@ -189,7 +191,7 @@ class IRBlock extends IRBlockBase {
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
final predicate postDominates(IRBlock block) { this.strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
@@ -199,16 +201,16 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
postDominates(result.getASuccessor()) and
not strictlyPostDominates(result)
this.postDominates(result.getASuccessor()) and
not this.strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
final predicate isReachableFromFunctionEntry() {
this = getEnclosingIRFunction().getEntryBlock() or
getAPredecessor().isReachableFromFunctionEntry()
this = this.getEnclosingIRFunction().getEntryBlock() or
this.getAPredecessor().isReachableFromFunctionEntry()
}
}

View File

@@ -46,12 +46,12 @@ class Operand extends TStageOperand {
/**
* Gets the location of the source code for this operand.
*/
final Language::Location getLocation() { result = getUse().getLocation() }
final Language::Location getLocation() { result = this.getUse().getLocation() }
/**
* Gets the function that contains this operand.
*/
final IRFunction getEnclosingIRFunction() { result = getUse().getEnclosingIRFunction() }
final IRFunction getEnclosingIRFunction() { result = this.getUse().getEnclosingIRFunction() }
/**
* Gets the `Instruction` that consumes this operand.
@@ -74,7 +74,7 @@ class Operand extends TStageOperand {
*/
final Instruction getDef() {
result = this.getAnyDef() and
getDefinitionOverlap() instanceof MustExactlyOverlap
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
@@ -82,7 +82,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = getUse() }
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
@@ -91,7 +91,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = getAnyDef() }
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
@@ -101,7 +101,9 @@ class Operand extends TStageOperand {
/**
* Holds if the result of the definition instruction does not exactly overlap this use.
*/
final predicate isDefinitionInexact() { not getDefinitionOverlap() instanceof MustExactlyOverlap }
final predicate isDefinitionInexact() {
not this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* Gets a prefix to use when dumping the operand in an operand list.
@@ -121,7 +123,7 @@ class Operand extends TStageOperand {
* For example: `this:r3_5`
*/
final string getDumpString() {
result = getDumpLabel() + getInexactSpecifier() + getDefinitionId()
result = this.getDumpLabel() + this.getInexactSpecifier() + this.getDefinitionId()
}
/**
@@ -129,9 +131,9 @@ class Operand extends TStageOperand {
* definition is not modeled in SSA.
*/
private string getDefinitionId() {
result = getAnyDef().getResultId()
result = this.getAnyDef().getResultId()
or
not exists(getAnyDef()) and result = "m?"
not exists(this.getAnyDef()) and result = "m?"
}
/**
@@ -140,7 +142,7 @@ class Operand extends TStageOperand {
* the empty string.
*/
private string getInexactSpecifier() {
if isDefinitionInexact() then result = "~" else result = ""
if this.isDefinitionInexact() then result = "~" else result = ""
}
/**
@@ -155,7 +157,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
Language::LanguageType getLanguageType() { result = getAnyDef().getResultLanguageType() }
Language::LanguageType getLanguageType() { result = this.getAnyDef().getResultLanguageType() }
/**
* Gets the language-neutral type of the value consumed by this operand. This is usually the same
@@ -164,7 +166,7 @@ class Operand extends TStageOperand {
* from the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
final IRType getIRType() { result = getLanguageType().getIRType() }
final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the value consumed by this operand. This is usually the same as the
@@ -173,7 +175,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
final Language::Type getType() { getLanguageType().hasType(result, _) }
final Language::Type getType() { this.getLanguageType().hasType(result, _) }
/**
* Holds if the value consumed by this operand is a glvalue. If this
@@ -182,13 +184,13 @@ class Operand extends TStageOperand {
* not hold, the value of the operand represents a value whose type is
* given by `getType()`.
*/
final predicate isGLValue() { getLanguageType().hasType(_, true) }
final predicate isGLValue() { this.getLanguageType().hasType(_, true) }
/**
* Gets the size of the value consumed by this operand, in bytes. If the operand does not have
* a known constant size, this predicate does not hold.
*/
final int getSize() { result = getLanguageType().getByteSize() }
final int getSize() { result = this.getLanguageType().getByteSize() }
}
/**
@@ -205,7 +207,7 @@ class MemoryOperand extends Operand {
/**
* Gets the kind of memory access performed by the operand.
*/
MemoryAccessKind getMemoryAccess() { result = getUse().getOpcode().getReadMemoryAccess() }
MemoryAccessKind getMemoryAccess() { result = this.getUse().getOpcode().getReadMemoryAccess() }
/**
* Holds if the memory access performed by this operand will not always read from every bit in the
@@ -215,7 +217,7 @@ class MemoryOperand extends Operand {
* conservative estimate of the memory that might actually be accessed at runtime (for example,
* the global side effects of a function call).
*/
predicate hasMayReadMemoryAccess() { getUse().getOpcode().hasMayReadMemoryAccess() }
predicate hasMayReadMemoryAccess() { this.getUse().getOpcode().hasMayReadMemoryAccess() }
/**
* Returns the operand that holds the memory address from which the current operand loads its
@@ -223,8 +225,8 @@ class MemoryOperand extends Operand {
* is `r1`.
*/
final AddressOperand getAddressOperand() {
getMemoryAccess().usesAddressOperand() and
result.getUse() = getUse()
this.getMemoryAccess().usesAddressOperand() and
result.getUse() = this.getUse()
}
}
@@ -294,7 +296,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
final override Overlap getDefinitionOverlap() { this.hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
@@ -449,13 +451,17 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
final override Overlap getDefinitionOverlap() { result = overlap }
final override int getDumpSortOrder() { result = 11 + getPredecessorBlock().getDisplayIndex() }
final override string getDumpLabel() {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
final override int getDumpSortOrder() {
result = 11 + this.getPredecessorBlock().getDisplayIndex()
}
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
final override string getDumpLabel() {
result = "from " + this.getPredecessorBlock().getDisplayIndex().toString() + ":"
}
final override string getDumpId() {
result = this.getPredecessorBlock().getDisplayIndex().toString()
}
/**
* Gets the predecessor block from which this value comes.

View File

@@ -24,7 +24,7 @@ class IRBlockBase extends TIRBlock {
final string toString() { result = getFirstInstruction(this).toString() }
/** Gets the source location of the first non-`Phi` instruction in this block. */
final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
final Language::Location getLocation() { result = this.getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
@@ -39,7 +39,7 @@ class IRBlockBase extends TIRBlock {
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
funcBlock.getEnclosingFunction() = getEnclosingFunction() and
funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
@@ -59,15 +59,15 @@ class IRBlockBase extends TIRBlock {
* Get the `Phi` instructions that appear at the start of this block.
*/
final PhiInstruction getAPhiInstruction() {
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
Construction::getPhiInstructionBlockStart(result) = this.getFirstInstruction()
}
/**
* Gets an instruction in this block. This includes `Phi` instructions.
*/
final Instruction getAnInstruction() {
result = getInstruction(_) or
result = getAPhiInstruction()
result = this.getInstruction(_) or
result = this.getAPhiInstruction()
}
/**
@@ -78,7 +78,9 @@ class IRBlockBase extends TIRBlock {
/**
* Gets the last instruction in this block.
*/
final Instruction getLastInstruction() { result = getInstruction(getInstructionCount() - 1) }
final Instruction getLastInstruction() {
result = this.getInstruction(this.getInstructionCount() - 1)
}
/**
* Gets the number of non-`Phi` instructions in this block.
@@ -149,7 +151,7 @@ class IRBlock extends IRBlockBase {
* Block `A` dominates block `B` if any control flow path from the entry block of the function to
* block `B` must pass through block `A`. A block always dominates itself.
*/
final predicate dominates(IRBlock block) { strictlyDominates(block) or this = block }
final predicate dominates(IRBlock block) { this.strictlyDominates(block) or this = block }
/**
* Gets a block on the dominance frontier of this block.
@@ -159,8 +161,8 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock dominanceFrontier() {
dominates(result.getAPredecessor()) and
not strictlyDominates(result)
this.dominates(result.getAPredecessor()) and
not this.strictlyDominates(result)
}
/**
@@ -189,7 +191,7 @@ class IRBlock extends IRBlockBase {
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
final predicate postDominates(IRBlock block) { this.strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
@@ -199,16 +201,16 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
postDominates(result.getASuccessor()) and
not strictlyPostDominates(result)
this.postDominates(result.getASuccessor()) and
not this.strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
final predicate isReachableFromFunctionEntry() {
this = getEnclosingIRFunction().getEntryBlock() or
getAPredecessor().isReachableFromFunctionEntry()
this = this.getEnclosingIRFunction().getEntryBlock() or
this.getAPredecessor().isReachableFromFunctionEntry()
}
}

View File

@@ -46,12 +46,12 @@ class Operand extends TStageOperand {
/**
* Gets the location of the source code for this operand.
*/
final Language::Location getLocation() { result = getUse().getLocation() }
final Language::Location getLocation() { result = this.getUse().getLocation() }
/**
* Gets the function that contains this operand.
*/
final IRFunction getEnclosingIRFunction() { result = getUse().getEnclosingIRFunction() }
final IRFunction getEnclosingIRFunction() { result = this.getUse().getEnclosingIRFunction() }
/**
* Gets the `Instruction` that consumes this operand.
@@ -74,7 +74,7 @@ class Operand extends TStageOperand {
*/
final Instruction getDef() {
result = this.getAnyDef() and
getDefinitionOverlap() instanceof MustExactlyOverlap
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
@@ -82,7 +82,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = getUse() }
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
@@ -91,7 +91,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = getAnyDef() }
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
@@ -101,7 +101,9 @@ class Operand extends TStageOperand {
/**
* Holds if the result of the definition instruction does not exactly overlap this use.
*/
final predicate isDefinitionInexact() { not getDefinitionOverlap() instanceof MustExactlyOverlap }
final predicate isDefinitionInexact() {
not this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* Gets a prefix to use when dumping the operand in an operand list.
@@ -121,7 +123,7 @@ class Operand extends TStageOperand {
* For example: `this:r3_5`
*/
final string getDumpString() {
result = getDumpLabel() + getInexactSpecifier() + getDefinitionId()
result = this.getDumpLabel() + this.getInexactSpecifier() + this.getDefinitionId()
}
/**
@@ -129,9 +131,9 @@ class Operand extends TStageOperand {
* definition is not modeled in SSA.
*/
private string getDefinitionId() {
result = getAnyDef().getResultId()
result = this.getAnyDef().getResultId()
or
not exists(getAnyDef()) and result = "m?"
not exists(this.getAnyDef()) and result = "m?"
}
/**
@@ -140,7 +142,7 @@ class Operand extends TStageOperand {
* the empty string.
*/
private string getInexactSpecifier() {
if isDefinitionInexact() then result = "~" else result = ""
if this.isDefinitionInexact() then result = "~" else result = ""
}
/**
@@ -155,7 +157,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
Language::LanguageType getLanguageType() { result = getAnyDef().getResultLanguageType() }
Language::LanguageType getLanguageType() { result = this.getAnyDef().getResultLanguageType() }
/**
* Gets the language-neutral type of the value consumed by this operand. This is usually the same
@@ -164,7 +166,7 @@ class Operand extends TStageOperand {
* from the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
final IRType getIRType() { result = getLanguageType().getIRType() }
final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the value consumed by this operand. This is usually the same as the
@@ -173,7 +175,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
final Language::Type getType() { getLanguageType().hasType(result, _) }
final Language::Type getType() { this.getLanguageType().hasType(result, _) }
/**
* Holds if the value consumed by this operand is a glvalue. If this
@@ -182,13 +184,13 @@ class Operand extends TStageOperand {
* not hold, the value of the operand represents a value whose type is
* given by `getType()`.
*/
final predicate isGLValue() { getLanguageType().hasType(_, true) }
final predicate isGLValue() { this.getLanguageType().hasType(_, true) }
/**
* Gets the size of the value consumed by this operand, in bytes. If the operand does not have
* a known constant size, this predicate does not hold.
*/
final int getSize() { result = getLanguageType().getByteSize() }
final int getSize() { result = this.getLanguageType().getByteSize() }
}
/**
@@ -205,7 +207,7 @@ class MemoryOperand extends Operand {
/**
* Gets the kind of memory access performed by the operand.
*/
MemoryAccessKind getMemoryAccess() { result = getUse().getOpcode().getReadMemoryAccess() }
MemoryAccessKind getMemoryAccess() { result = this.getUse().getOpcode().getReadMemoryAccess() }
/**
* Holds if the memory access performed by this operand will not always read from every bit in the
@@ -215,7 +217,7 @@ class MemoryOperand extends Operand {
* conservative estimate of the memory that might actually be accessed at runtime (for example,
* the global side effects of a function call).
*/
predicate hasMayReadMemoryAccess() { getUse().getOpcode().hasMayReadMemoryAccess() }
predicate hasMayReadMemoryAccess() { this.getUse().getOpcode().hasMayReadMemoryAccess() }
/**
* Returns the operand that holds the memory address from which the current operand loads its
@@ -223,8 +225,8 @@ class MemoryOperand extends Operand {
* is `r1`.
*/
final AddressOperand getAddressOperand() {
getMemoryAccess().usesAddressOperand() and
result.getUse() = getUse()
this.getMemoryAccess().usesAddressOperand() and
result.getUse() = this.getUse()
}
}
@@ -294,7 +296,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
final override Overlap getDefinitionOverlap() { this.hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
@@ -449,13 +451,17 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
final override Overlap getDefinitionOverlap() { result = overlap }
final override int getDumpSortOrder() { result = 11 + getPredecessorBlock().getDisplayIndex() }
final override string getDumpLabel() {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
final override int getDumpSortOrder() {
result = 11 + this.getPredecessorBlock().getDisplayIndex()
}
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
final override string getDumpLabel() {
result = "from " + this.getPredecessorBlock().getDisplayIndex().toString() + ":"
}
final override string getDumpId() {
result = this.getPredecessorBlock().getDisplayIndex().toString()
}
/**
* Gets the predecessor block from which this value comes.

View File

@@ -18,10 +18,11 @@ Overlap getOverlap(IntValue defStart, IntValue defEnd, IntValue useStart, IntVal
else
if isLE(defStart, useStart) and isGE(defEnd, useEnd)
then result instanceof MustTotallyOverlap
else
if isLE(defEnd, useStart) or isGE(defStart, useEnd)
then none()
else result instanceof MayPartiallyOverlap
else (
not isLE(defEnd, useStart) and
not isGE(defStart, useEnd) and
result instanceof MayPartiallyOverlap
)
}
/**

View File

@@ -56,7 +56,7 @@ private class MallocAllocationFunction extends AllocationFunction {
]) and
sizeArg = 1
or
hasGlobalName(["HeapAlloc"]) and // HeapAlloc(heap, flags, size)
hasGlobalName("HeapAlloc") and // HeapAlloc(heap, flags, size)
sizeArg = 2
or
hasGlobalName([

View File

@@ -365,7 +365,7 @@ class GetsBW extends BufferWriteCall {
/**
* Gets the index of the parameter that is the maximum number of characters to be read.
*/
int getParamSize() { if exists(getArgument(1)) then result = 1 else none() }
int getParamSize() { exists(getArgument(1)) and result = 1 }
override Type getBufferType() { result = this.getTarget().getParameter(0).getUnspecifiedType() }

1207
cpp/ql/lib/tutorial.qll Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -60,9 +60,7 @@ class SuppressionComment extends Comment {
/**
* The scope of an alert suppression comment.
*/
class SuppressionScope extends ElementBase {
SuppressionScope() { this instanceof SuppressionComment }
class SuppressionScope extends ElementBase instanceof SuppressionComment {
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
@@ -73,7 +71,7 @@ class SuppressionScope extends ElementBase {
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn)
super.covers(filepath, startline, startcolumn, endline, endcolumn)
}
}

View File

@@ -1,16 +0,0 @@
/**
* @name Extraction errors
* @description List all extraction errors for files in the source code directory.
* @kind diagnostic
* @id cpp/diagnostics/extraction-errors
*/
import cpp
import ExtractionErrors
from ExtractionError error
where
error instanceof ExtractionUnknownError or
exists(error.getFile().getRelativePath())
select error, "Extraction failed in " + error.getFile() + " with error " + error.getErrorMessage(),
error.getSeverity()

View File

@@ -1,12 +1,12 @@
/**
* Provides a common hierarchy of all types of errors that can occur during extraction.
* Provides a common hierarchy of all types of problems that can occur during extraction.
*/
import cpp
/*
* A note about how the C/C++ extractor emits diagnostics:
* When the extractor frontend encounters an error, it emits a diagnostic message,
* When the extractor frontend encounters a problem, it emits a diagnostic message,
* that includes a message, location and severity.
* However, that process is best-effort and may fail (e.g. due to lack of memory).
* Thus, if the extractor emitted at least one diagnostic of severity discretionary
@@ -15,17 +15,17 @@ import cpp
* In the common case, this means that a compilation during which one or more errors happened also gets
* the catch-all diagnostic.
* This diagnostic has the empty string as file path.
* We filter out these useless diagnostics if there is at least one error-level diagnostic
* We filter out these useless diagnostics if there is at least one warning-level diagnostic
* for the affected compilation in the database.
* Otherwise, we show it to indicate that something went wrong and that we
* don't know what exactly happened.
*/
/**
* An error that, if present, leads to a file being marked as non-successfully extracted.
* A problem with a file that, if present, leads to a file being marked as non-successfully extracted.
*/
class ReportableError extends Diagnostic {
ReportableError() {
class ReportableWarning extends Diagnostic {
ReportableWarning() {
(
this instanceof CompilerDiscretionaryError or
this instanceof CompilerError or
@@ -36,39 +36,35 @@ class ReportableError extends Diagnostic {
}
}
private newtype TExtractionError =
TReportableError(ReportableError err) or
private newtype TExtractionProblem =
TReportableWarning(ReportableWarning err) or
TCompilationFailed(Compilation c, File f) {
f = c.getAFileCompiled() and not c.normalTermination()
} or
// Show the catch-all diagnostic (see note above) only if we haven't seen any other error-level diagnostic
// for that compilation
TUnknownError(CompilerError err) {
not exists(ReportableError e | e.getCompilation() = err.getCompilation())
TUnknownProblem(CompilerError err) {
not exists(ReportableWarning e | e.getCompilation() = err.getCompilation())
}
/**
* Superclass for the extraction error hierarchy.
* Superclass for the extraction problem hierarchy.
*/
class ExtractionError extends TExtractionError {
/** Gets the string representation of the error. */
class ExtractionProblem extends TExtractionProblem {
/** Gets the string representation of the problem. */
string toString() { none() }
/** Gets the error message for this error. */
string getErrorMessage() { none() }
/** Gets the problem message for this problem. */
string getProblemMessage() { none() }
/** Gets the file this error occured in. */
/** Gets the file this problem occured in. */
File getFile() { none() }
/** Gets the location this error occured in. */
/** Gets the location this problem occured in. */
Location getLocation() { none() }
/** Gets the SARIF severity of this error. */
int getSeverity() {
// Unfortunately, we can't distinguish between errors and fatal errors in SARIF,
// so all errors have severity 2.
result = 2
}
/** Gets the SARIF severity of this problem. */
int getSeverity() { none() }
}
/**
@@ -79,7 +75,7 @@ class ExtractionError extends TExtractionError {
* - stack overflow
* - out of memory
*/
class ExtractionUnrecoverableError extends ExtractionError, TCompilationFailed {
class ExtractionUnrecoverableError extends ExtractionProblem, TCompilationFailed {
Compilation c;
File f;
@@ -89,49 +85,67 @@ class ExtractionUnrecoverableError extends ExtractionError, TCompilationFailed {
result = "Unrecoverable extraction error while compiling " + f.toString()
}
override string getErrorMessage() { result = "unrecoverable compilation failure." }
override string getProblemMessage() { result = "unrecoverable compilation failure." }
override File getFile() { result = f }
override Location getLocation() { result = f.getLocation() }
override int getSeverity() {
// These extractor errors break the analysis, so we mark them in SARIF as
// [errors](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#_Toc10541338).
result = 2
}
}
/**
* A recoverable extraction error.
* A recoverable extraction warning.
* These are compiler errors from the frontend.
* Upon encountering one of these, we still continue extraction, but the
* database will be incomplete for that file.
*/
class ExtractionRecoverableError extends ExtractionError, TReportableError {
ReportableError err;
class ExtractionRecoverableWarning extends ExtractionProblem, TReportableWarning {
ReportableWarning err;
ExtractionRecoverableError() { this = TReportableError(err) }
ExtractionRecoverableWarning() { this = TReportableWarning(err) }
override string toString() { result = "Recoverable extraction error: " + err }
override string getErrorMessage() { result = err.getFullMessage() }
override string getProblemMessage() { result = err.getFullMessage() }
override File getFile() { result = err.getFile() }
override Location getLocation() { result = err.getLocation() }
override int getSeverity() {
// Recoverable extraction problems don't tend to break the analysis, so we mark them in SARIF as
// [warnings](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#_Toc10541338).
result = 1
}
}
/**
* An unknown error happened during extraction.
* These are only displayed if we know that we encountered an error during extraction,
* An unknown problem happened during extraction.
* These are only displayed if we know that we encountered an problem during extraction,
* but, for some reason, failed to emit a proper diagnostic with location information
* and error message.
* and problem message.
*/
class ExtractionUnknownError extends ExtractionError, TUnknownError {
class ExtractionUnknownProblem extends ExtractionProblem, TUnknownProblem {
CompilerError err;
ExtractionUnknownError() { this = TUnknownError(err) }
ExtractionUnknownProblem() { this = TUnknownProblem(err) }
override string toString() { result = "Unknown extraction error: " + err }
override string toString() { result = "Unknown extraction problem: " + err }
override string getErrorMessage() { result = err.getFullMessage() }
override string getProblemMessage() { result = err.getFullMessage() }
override File getFile() { result = err.getFile() }
override Location getLocation() { result = err.getLocation() }
override int getSeverity() {
// Unknown extraction problems don't tend to break the analysis, so we mark them in SARIF as
// [warnings](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#_Toc10541338).
result = 1
}
}

View File

@@ -0,0 +1,18 @@
/**
* @name Extraction warnings
* @description List all extraction warnings for files in the source code directory.
* @kind diagnostic
* @id cpp/diagnostics/extraction-warnings
*/
import cpp
import ExtractionProblems
from ExtractionProblem warning
where
warning instanceof ExtractionRecoverableWarning and exists(warning.getFile().getRelativePath())
or
warning instanceof ExtractionUnknownProblem
select warning,
"Extraction failed in " + warning.getFile() + " with warning " + warning.getProblemMessage(),
warning.getSeverity()

View File

@@ -13,6 +13,9 @@ string describe(Compilation c) {
else result = "extractor invocation " + concat(int i | | c.getArgument(i), " " order by i)
}
/** Gets the SARIF severity level that indicates an error. */
private int getErrorSeverity() { result = 2 }
from Compilation c
where not c.normalTermination()
select "Extraction aborted for " + describe(c)
select "Extraction aborted for " + describe(c), getErrorSeverity()

View File

@@ -1,15 +1,15 @@
/**
* @name Successfully extracted files
* @description Lists all files in the source code directory that were extracted without encountering an error in the file.
* @description Lists all files in the source code directory that were extracted without encountering a problem in the file.
* @kind diagnostic
* @id cpp/diagnostics/successfully-extracted-files
*/
import cpp
import ExtractionErrors
import ExtractionProblems
from File f
where
not exists(ExtractionError e | e.getFile() = f) and
not exists(ExtractionProblem e | e.getFile() = f) and
exists(f.getRelativePath())
select f, ""
select f, "File successfully extracted"

View File

@@ -166,6 +166,7 @@ class VarAnalyzableExpr extends AnalyzableExpr, VariableAccess {
* Holds if `t` is not an instance of `IntegralType`,
* or if `me` cannot be proven to not overflow
*/
pragma[inline]
predicate overflows(MulExpr me, Type t) {
t instanceof IntegralType
implies

View File

@@ -50,10 +50,7 @@ where
// If either of the operands is constant, then don't include it.
(
if cmp.getLeftOperand().isConstant()
then
if cmp.getRightOperand().isConstant()
then none() // Both operands are constant so don't create a message.
else reason = rightReason
then not cmp.getRightOperand().isConstant() and reason = rightReason
else
if cmp.getRightOperand().isConstant()
then reason = leftReason

View File

@@ -53,6 +53,7 @@ class ImproperNullTerminationReachability extends StackVariableReachabilityWithR
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
exprDefinition(v, node, _) or
mayAddNullTerminator(node, v.getAnAccess()) or
node.(AddressOfExpr).getOperand() = v.getAnAccess() or // address taken
isSinkActual(node, v) // only report first use
}
}

View File

@@ -121,16 +121,14 @@ predicate exprSourceType(Expr use, Type sourceType, Location sourceLoc) {
else
if use instanceof CrementOperation
then exprSourceType(use.(CrementOperation).getOperand(), sourceType, sourceLoc)
else
else (
// Conversions are not in the AST, so ignore them.
if use instanceof Conversion
then none()
else (
// Source expressions
sourceType = use.getUnspecifiedType() and
isPointerType(sourceType) and
sourceLoc = use.getLocation()
)
not use instanceof Conversion and
// Source expressions
sourceType = use.getUnspecifiedType() and
isPointerType(sourceType) and
sourceLoc = use.getLocation()
)
}
/**

View File

@@ -0,0 +1,18 @@
...
int myFclose(FILE * fmy)
{
if(!fclose(fmy)) {
fmy = NULL;
return 0;
}
return -1;
}
...
fe = fopen("myFile.txt", "wt");
...
fclose(fe); // BAD
...
fe = fopen("myFile.txt", "wt");
...
myFclose(fe); // GOOD
...

View File

@@ -0,0 +1,23 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>The presence of a shell function with additional check indicates the possible risks of the call. Use this check everywhere.</p>
</overview>
<example>
<p>The following example demonstrates fallacious and fixed methods of using wrapper functions.</p>
<sample src="FindWrapperFunctions.cpp" />
</example>
<references>
<li>
CERT C Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/java/JNI00-J.+Define+wrappers+around+native+methods">JNI00-J. Define wrappers around native methods</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,141 @@
/**
* @name Missed opportunity to call wrapper function
* @description If a wrapper function is defined for a given function, any call to the given function should be via the wrapper function.
* @kind problem
* @id cpp/call-to-function-without-wrapper
* @problem.severity warning
* @precision medium
* @tags correctness
* maintainability
* security
* external/cwe/cwe-1041
*/
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.commons.Assertions
/**
* A function call that is used in error situations (logging, throwing an exception, abnormal termination).
*/
class CallUsedToHandleErrors extends FunctionCall {
CallUsedToHandleErrors() {
// call that is known to not return
not exists(this.(ControlFlowNode).getASuccessor())
or
// call throwing an exception
exists(ThrowExpr tex | tex = this.(ControlFlowNode).getASuccessor())
or
// call logging a message, possibly an error
exists(FormattingFunction ff | ff = this.(ControlFlowNode).getASuccessor())
or
// enabling recursive search
exists(CallUsedToHandleErrors fr | getTarget() = fr.getEnclosingFunction())
}
}
/** Holds if the conditions for a call outside the wrapper function are met. */
predicate conditionsOutsideWrapper(FunctionCall fcp) {
fcp.getNumberOfArguments() > 0 and
not exists(ConditionalStmt cdtmp | fcp.getEnclosingStmt().getParentStmt*() = cdtmp) and
not exists(Loop lptmp | fcp.getEnclosingStmt().getParentStmt*() = lptmp) and
not exists(ReturnStmt rttmp | fcp.getEnclosingStmt().getParentStmt*() = rttmp) and
not exists(FunctionCall fctmp2 | fcp = fctmp2.getAnArgument().getAChild*()) and
not exists(Assignment astmp | fcp = astmp.getRValue().getAChild*()) and
not exists(Initializer intmp | fcp = intmp.getExpr().getAChild*()) and
not exists(Assertion astmp | fcp = astmp.getAsserted().getAChild*()) and
not exists(Operation optmp | fcp = optmp.getAChild*()) and
not exists(ArrayExpr aetmp | fcp = aetmp.getAChild*()) and
not exists(ExprCall ectmp | fcp = ectmp.getAnArgument().getAChild*())
}
/** Holds if the conditions for calling `fcp` inside the `fnp` wrapper function are met. */
pragma[inline]
predicate conditionsInsideWrapper(FunctionCall fcp, Function fnp) {
not exists(FunctionCall fctmp2 |
fctmp2.getEnclosingFunction() = fnp and fcp = fctmp2.getAnArgument().getAChild*()
) and
not fcp instanceof CallUsedToHandleErrors and
not fcp.getAnArgument().isConstant() and
fcp.getEnclosingFunction() = fnp and
fnp.getNumberOfParameters() > 0 and
// the call arguments must be passed through the arguments of the wrapper function
forall(int i | i in [0 .. fcp.getNumberOfArguments() - 1] |
globalValueNumber(fcp.getArgument(i)) = globalValueNumber(fnp.getAParameter().getAnAccess())
) and
// there should be no more than one required call inside the wrapper function
not exists(FunctionCall fctmp |
fctmp.getTarget() = fcp.getTarget() and
fctmp.getFile() = fcp.getFile() and
fctmp != fcp and
fctmp.getEnclosingFunction() = fnp
) and
// inside the wrapper function there should be no calls without paths to the desired function
not exists(FunctionCall fctmp |
fctmp.getEnclosingFunction() = fnp and
fctmp.getFile() = fcp.getFile() and
fctmp != fcp and
(
fctmp = fcp.getAPredecessor+()
or
not exists(FunctionCall fctmp1 |
fctmp1 = fcp and
(
fctmp.getASuccessor+() = fctmp1 or
fctmp.getAPredecessor+() = fctmp1
)
)
)
)
}
/** Holds if the conditions for the wrapper function are met. */
pragma[inline]
predicate conditionsForWrapper(FunctionCall fcp, Function fnp) {
not exists(ExprCall ectmp | fnp = ectmp.getEnclosingFunction()) and
not exists(Loop lp | lp.getEnclosingFunction() = fnp) and
not exists(SwitchStmt sw | sw.getEnclosingFunction() = fnp) and
not fnp instanceof Operator and
// inside the wrapper function there should be checks of arguments or the result,
// perhaps by means of passing the latter as an argument to some function
(
exists(IfStmt ifs |
ifs.getEnclosingFunction() = fnp and
(
globalValueNumber(ifs.getCondition().getAChild*()) = globalValueNumber(fcp.getAnArgument()) and
ifs.getASuccessor*() = fcp
or
ifs.getCondition().getAChild() = fcp
)
)
or
exists(FunctionCall fctmp |
fctmp.getEnclosingFunction() = fnp and
globalValueNumber(fctmp.getAnArgument().getAChild*()) = globalValueNumber(fcp)
)
) and
// inside the wrapper function there must be a function call to handle the error
exists(CallUsedToHandleErrors fctmp |
fctmp.getEnclosingFunction() = fnp and
forall(int i | i in [0 .. fnp.getNumberOfParameters() - 1] |
fnp.getParameter(i).getAnAccess().getTarget() =
fcp.getAnArgument().(VariableAccess).getTarget() or
fnp.getParameter(i).getUnspecifiedType() instanceof Class or
fnp.getParameter(i).getUnspecifiedType().(ReferenceType).getBaseType() instanceof Class or
fnp.getParameter(i).getAnAccess().getTarget() =
fctmp.getAnArgument().(VariableAccess).getTarget()
)
)
}
from FunctionCall fc, Function fn
where
exists(FunctionCall fctmp |
conditionsInsideWrapper(fctmp, fn) and
conditionsForWrapper(fctmp, fn) and
conditionsOutsideWrapper(fc) and
fctmp.getTarget() = fc.getTarget() and
fc.getEnclosingFunction() != fn and
fc.getEnclosingFunction().getMetrics().getNumberOfCalls() > fn.getMetrics().getNumberOfCalls()
)
select fc, "Consider changing the call to $@", fn, fn.getName()

View File

@@ -230,13 +230,13 @@ predicate leakedInSameMethod(Resource r, Expr acquire) {
)
)
)
or
exists(FunctionAccess fa, string kind |
// the address of a function that releases `r` is taken (and likely
// used to release `r` at some point).
r.acquisitionWithRequiredKind(acquire, kind) and
fa.getTarget() = r.getAReleaseExpr(kind).getEnclosingFunction()
)
)
or
exists(FunctionAccess fa, string kind |
// the address of a function that releases `r` is taken (and likely
// used to release `r` at some point).
r.acquisitionWithRequiredKind(acquire, kind) and
fa.getTarget() = r.getAReleaseExpr(kind).getEnclosingFunction()
)
}

View File

@@ -4,7 +4,7 @@
* (in that the `.expected` file should always be empty).
*
* To add this framework to a new language:
* - Add a file `InlineExpectationsTestPrivate.qll` that defines a `LineComment` class. This class
* - Add a file `InlineExpectationsTestPrivate.qll` that defines a `ExpectationComment` class. This class
* must support a `getContents` method that returns the contents of the given comment, _excluding_
* the comment indicator itself. It should also define `toString` and `getLocation` as usual.
*
@@ -60,8 +60,8 @@
*
* Example:
* ```cpp
* int i = x + 5; // $const=5
* int j = y + (7 - 3) // $const=7 const=3 const=4 // The result of the subtraction is a constant.
* int i = x + 5; // $ const=5
* int j = y + (7 - 3) // $ const=7 const=3 const=4 // The result of the subtraction is a constant.
* ```
*
* For tests that contain known missing and spurious results, it is possible to further
@@ -194,7 +194,7 @@ private int getEndOfColumnPosition(int start, string content) {
}
private predicate getAnExpectation(
LineComment comment, TColumn column, string expectation, string tags, string value
ExpectationComment comment, TColumn column, string expectation, string tags, string value
) {
exists(string content |
content = comment.getContents().regexpCapture(expectationCommentPattern(), 1) and
@@ -247,14 +247,14 @@ private newtype TFailureLocatable =
) {
test.hasActualResult(location, element, tag, value)
} or
TValidExpectation(LineComment comment, string tag, string value, string knownFailure) {
TValidExpectation(ExpectationComment comment, string tag, string value, string knownFailure) {
exists(TColumn column, string tags |
getAnExpectation(comment, column, _, tags, value) and
tag = tags.splitAt(",") and
knownFailure = getColumnString(column)
)
} or
TInvalidExpectation(LineComment comment, string expectation) {
TInvalidExpectation(ExpectationComment comment, string expectation) {
getAnExpectation(comment, _, expectation, _, _) and
not expectation.regexpMatch(expectationPattern())
}
@@ -292,7 +292,7 @@ class ActualResult extends FailureLocatable, TActualResult {
}
abstract private class Expectation extends FailureLocatable {
LineComment comment;
ExpectationComment comment;
override string toString() { result = comment.toString() }

View File

@@ -1,16 +1,16 @@
import cpp
private newtype TLineComment = MkLineComment(CppStyleComment c)
private newtype TExpectationComment = MkExpectationComment(CppStyleComment c)
/**
* Represents a line comment in the CPP style.
* Unlike the `CppStyleComment` class, however, the string returned by `getContents` does _not_
* include the preceding comment marker (`//`).
*/
class LineComment extends TLineComment {
class ExpectationComment extends TExpectationComment {
CppStyleComment comment;
LineComment() { this = MkLineComment(comment) }
ExpectationComment() { this = MkExpectationComment(comment) }
/** Returns the contents of the given comment, _without_ the preceding comment marker (`//`). */
string getContents() { result = comment.getContents().suffix(2) }

View File

@@ -0,0 +1 @@
| test.cpp:23:3:23:8 | call to fclose | Consider changing the call to $@ | test.cpp:9:6:9:13 | myFclose | myFclose |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-1041/FindWrapperFunctions.ql

View File

@@ -0,0 +1,27 @@
#define NULL (0)
typedef int FILE;
FILE *fopen(const char *filename, const char *mode);
int fclose(FILE *stream);
extern FILE * fe;
extern int printf(const char *fmt, ...);
void exit(int status);
void myFclose(FILE * fmy)
{
int i;
if(fmy) {
i = fclose(fmy);
fmy = NULL;
printf("close end is code %d",i);
if(i!=0) exit(1);
}
}
int main(int argc, char *argv[])
{
fe = fopen("myFile.txt", "wt");
fclose(fe); // BAD
fe = fopen("myFile.txt", "wt");
myFclose(fe); // GOOD
return 0;
}

View File

@@ -1,27 +1,29 @@
| test.cpp:25:10:25:16 | buffer1 | Variable $@ may not be null terminated. | test.cpp:22:8:22:14 | buffer1 | buffer1 |
| test.cpp:26:10:26:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:23:8:23:14 | buffer2 | buffer2 |
| test.cpp:39:10:39:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:35:8:35:14 | buffer2 | buffer2 |
| test.cpp:59:10:59:13 | ptr1 | Variable $@ may not be null terminated. | test.cpp:56:9:56:12 | ptr1 | ptr1 |
| test.cpp:69:10:69:16 | buffer1 | Variable $@ may not be null terminated. | test.cpp:64:8:64:14 | buffer1 | buffer1 |
| test.cpp:70:10:70:12 | ptr | Variable $@ may not be null terminated. | test.cpp:64:8:64:14 | buffer1 | buffer1 |
| test.cpp:81:10:81:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:65:8:65:14 | buffer2 | buffer2 |
| test.cpp:82:10:82:12 | ptr | Variable $@ may not be null terminated. | test.cpp:65:8:65:14 | buffer2 | buffer2 |
| test.cpp:93:10:93:15 | buffer | Variable $@ may not be null terminated. | test.cpp:86:8:86:13 | buffer | buffer |
| test.cpp:116:10:116:15 | buffer | Variable $@ may not be null terminated. | test.cpp:109:8:109:13 | buffer | buffer |
| test.cpp:130:14:130:19 | buffer | Variable $@ may not be null terminated. | test.cpp:127:7:127:12 | buffer | buffer |
| test.cpp:139:10:139:15 | buffer | Variable $@ may not be null terminated. | test.cpp:136:8:136:13 | buffer | buffer |
| test.cpp:147:14:147:19 | buffer | Variable $@ may not be null terminated. | test.cpp:143:8:143:13 | buffer | buffer |
| test.cpp:182:10:182:15 | buffer | Variable $@ may not be null terminated. | test.cpp:178:8:178:13 | buffer | buffer |
| test.cpp:234:10:234:15 | buffer | Variable $@ may not be null terminated. | test.cpp:232:8:232:13 | buffer | buffer |
| test.cpp:262:10:262:15 | buffer | Variable $@ may not be null terminated. | test.cpp:259:8:259:13 | buffer | buffer |
| test.cpp:283:10:283:15 | buffer | Variable $@ may not be null terminated. | test.cpp:280:8:280:13 | buffer | buffer |
| test.cpp:300:10:300:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:295:8:295:14 | buffer2 | buffer2 |
| test.cpp:312:10:312:15 | buffer | Variable $@ may not be null terminated. | test.cpp:308:8:308:13 | buffer | buffer |
| test.cpp:327:18:327:23 | buffer | Variable $@ may not be null terminated. | test.cpp:326:8:326:13 | buffer | buffer |
| test.cpp:346:11:346:16 | buffer | Variable $@ may not be null terminated. | test.cpp:341:8:341:13 | buffer | buffer |
| test.cpp:26:10:26:16 | buffer1 | Variable $@ may not be null terminated. | test.cpp:23:8:23:14 | buffer1 | buffer1 |
| test.cpp:27:10:27:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:24:8:24:14 | buffer2 | buffer2 |
| test.cpp:40:10:40:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:36:8:36:14 | buffer2 | buffer2 |
| test.cpp:60:10:60:13 | ptr1 | Variable $@ may not be null terminated. | test.cpp:57:9:57:12 | ptr1 | ptr1 |
| test.cpp:70:10:70:16 | buffer1 | Variable $@ may not be null terminated. | test.cpp:65:8:65:14 | buffer1 | buffer1 |
| test.cpp:71:10:71:12 | ptr | Variable $@ may not be null terminated. | test.cpp:65:8:65:14 | buffer1 | buffer1 |
| test.cpp:82:10:82:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:66:8:66:14 | buffer2 | buffer2 |
| test.cpp:83:10:83:12 | ptr | Variable $@ may not be null terminated. | test.cpp:66:8:66:14 | buffer2 | buffer2 |
| test.cpp:94:10:94:15 | buffer | Variable $@ may not be null terminated. | test.cpp:87:8:87:13 | buffer | buffer |
| test.cpp:117:10:117:15 | buffer | Variable $@ may not be null terminated. | test.cpp:110:8:110:13 | buffer | buffer |
| test.cpp:131:14:131:19 | buffer | Variable $@ may not be null terminated. | test.cpp:128:7:128:12 | buffer | buffer |
| test.cpp:140:10:140:15 | buffer | Variable $@ may not be null terminated. | test.cpp:137:8:137:13 | buffer | buffer |
| test.cpp:148:14:148:19 | buffer | Variable $@ may not be null terminated. | test.cpp:144:8:144:13 | buffer | buffer |
| test.cpp:183:10:183:15 | buffer | Variable $@ may not be null terminated. | test.cpp:179:8:179:13 | buffer | buffer |
| test.cpp:236:10:236:15 | buffer | Variable $@ may not be null terminated. | test.cpp:234:8:234:13 | buffer | buffer |
| test.cpp:264:10:264:15 | buffer | Variable $@ may not be null terminated. | test.cpp:261:8:261:13 | buffer | buffer |
| test.cpp:285:10:285:15 | buffer | Variable $@ may not be null terminated. | test.cpp:282:8:282:13 | buffer | buffer |
| test.cpp:302:10:302:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:297:8:297:14 | buffer2 | buffer2 |
| test.cpp:314:10:314:15 | buffer | Variable $@ may not be null terminated. | test.cpp:310:8:310:13 | buffer | buffer |
| test.cpp:336:18:336:23 | buffer | Variable $@ may not be null terminated. | test.cpp:335:8:335:13 | buffer | buffer |
| test.cpp:355:11:355:16 | buffer | Variable $@ may not be null terminated. | test.cpp:350:8:350:13 | buffer | buffer |
| test.cpp:365:19:365:25 | buffer2 | Variable $@ may not be null terminated. | test.cpp:363:8:363:14 | buffer2 | buffer2 |
| test.cpp:392:17:392:22 | buffer | Variable $@ may not be null terminated. | test.cpp:390:8:390:13 | buffer | buffer |
| test.cpp:398:18:398:23 | buffer | Variable $@ may not be null terminated. | test.cpp:396:8:396:13 | buffer | buffer |
| test.cpp:444:10:444:15 | buffer | Variable $@ may not be null terminated. | test.cpp:442:8:442:13 | buffer | buffer |
| test.cpp:450:16:450:21 | buffer | Variable $@ may not be null terminated. | test.cpp:448:8:448:13 | buffer | buffer |
| test.cpp:364:11:364:16 | buffer | Variable $@ may not be null terminated. | test.cpp:359:8:359:13 | buffer | buffer |
| test.cpp:392:11:392:16 | buffer | Variable $@ may not be null terminated. | test.cpp:381:8:381:13 | buffer | buffer |
| test.cpp:410:11:410:16 | buffer | Variable $@ may not be null terminated. | test.cpp:397:8:397:13 | buffer | buffer |
| test.cpp:421:19:421:25 | buffer2 | Variable $@ may not be null terminated. | test.cpp:419:8:419:14 | buffer2 | buffer2 |
| test.cpp:448:17:448:22 | buffer | Variable $@ may not be null terminated. | test.cpp:446:8:446:13 | buffer | buffer |
| test.cpp:454:18:454:23 | buffer | Variable $@ may not be null terminated. | test.cpp:452:8:452:13 | buffer | buffer |
| test.cpp:513:10:513:15 | buffer | Variable $@ may not be null terminated. | test.cpp:511:8:511:13 | buffer | buffer |
| test.cpp:519:16:519:21 | buffer | Variable $@ may not be null terminated. | test.cpp:517:8:517:13 | buffer | buffer |

View File

@@ -1,2 +1,2 @@
| test.cpp:410:10:410:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:409:18:409:23 | buffer | User-provided value |
| test.cpp:425:10:425:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:424:9:424:14 | buffer | User-provided value |
| test.cpp:466:10:466:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:465:18:465:23 | buffer | User-provided value |
| test.cpp:481:10:481:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:480:9:480:14 | buffer | User-provided value |

View File

@@ -6,6 +6,7 @@ size_t strlen(const char *s);
char *strcpy(char *s1, const char *s2);
char *strcat(char *s1, const char *s2);
char *strdup(const char *s1);
long int strtol(const char* nptr, char** endptr, int base);
void *malloc(size_t size);
void *memset(void *s, int c, size_t n);
void *memcpy(void *s1, const void *s2, size_t n);
@@ -225,6 +226,7 @@ void test_readlink(int fd, const char *path, size_t sz)
void doNothing(char *data) { };
void doNothing2(const char *data);
void clearBuffer(char *data, size_t size);
char *id(char *data) { return data; }
void test_strcat()
{
@@ -318,6 +320,13 @@ void test_strcat()
clearBuffer(buffer, 1024);
strcat(buffer, "content"); // GOOD
}
{
char buffer[1024];
clearBuffer(id(buffer), 1024);
strcat(buffer, "content"); // GOOD
}
}
void test_strlen(bool cond1, bool cond2)
@@ -354,6 +363,53 @@ void test_strlen(bool cond1, bool cond2)
if (cond2)
strlen(buffer); // BAD
}
{
char buffer[1024];
if (cond1)
{
buffer[0] = 0;
} else {
buffer[0] = 0;
}
strlen(buffer); // GOOD
}
{
char buffer[1024];
int init = 0;
if (cond1)
{
buffer[0] = 0;
init = 1;
}
if (init != 0)
{
strlen(buffer); // GOOD [FALSE POSITIVE]
}
}
{
char buffer[1024];
int init = 0;
if (cond1)
{
buffer[0] = 0;
init = 1;
}
if (init == 0)
{
// ...
} else {
strlen(buffer); // GOOD [FALSE POSITIVE]
}
}
}
void test_strcpy()
@@ -434,6 +490,19 @@ void test_read_fread(int read_src, FILE *s)
}
}
void test_strtol()
{
{
char buffer[100];
char *after_ptr;
long int num;
strcpy(buffer, "123abc");
num = strtol("123abc", &after_ptr, 10);
strlen(after_ptr); // GOOD
}
}
int printf(const char *format, ...);
void test_printf(char *str)
@@ -466,3 +535,4 @@ void test_printf(char *str)
printf("%s", copied_str); // GOOD
}
}

View File

@@ -5,9 +5,13 @@
| test2.cpp:130:7:130:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:130:13:130:16 | path | filename | test2.cpp:128:21:128:27 | buf_ptr | checked |
| test2.cpp:157:7:157:10 | call to open | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:157:12:157:15 | path | filename | test2.cpp:155:6:155:9 | call to stat | checked |
| test2.cpp:170:7:170:10 | call to open | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:170:12:170:15 | path | filename | test2.cpp:168:6:168:10 | call to lstat | checked |
| test2.cpp:245:3:245:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:245:9:245:12 | path | filename | test2.cpp:238:6:238:10 | call to fopen | checked |
| test2.cpp:277:7:277:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:277:13:277:16 | path | filename | test2.cpp:275:6:275:11 | call to access | checked |
| test2.cpp:303:7:303:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:303:13:303:16 | path | filename | test2.cpp:301:7:301:12 | call to access | checked |
| test2.cpp:317:7:317:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:317:13:317:16 | path | filename | test2.cpp:313:6:313:11 | call to access | checked |
| test2.cpp:348:3:348:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:348:9:348:12 | path | filename | test2.cpp:341:6:341:10 | call to fopen | checked |
| test2.cpp:356:3:356:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:356:9:356:13 | path2 | filename | test2.cpp:354:7:354:12 | call to rename | checked |
| test2.cpp:209:7:209:10 | call to open | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:209:12:209:15 | path | filename | test2.cpp:207:6:207:9 | call to stat | checked |
| test2.cpp:228:8:228:11 | call to open | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:228:13:228:16 | path | filename | test2.cpp:224:6:224:9 | call to stat | checked |
| test2.cpp:228:8:228:11 | call to open | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:228:13:228:16 | path | filename | test2.cpp:226:7:226:9 | buf | checked |
| test2.cpp:249:6:249:10 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:249:12:249:15 | path | filename | test2.cpp:244:6:244:9 | call to stat | checked |
| test2.cpp:297:3:297:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:297:9:297:12 | path | filename | test2.cpp:290:6:290:10 | call to fopen | checked |
| test2.cpp:329:7:329:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:329:13:329:16 | path | filename | test2.cpp:327:6:327:11 | call to access | checked |
| test2.cpp:355:7:355:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:355:13:355:16 | path | filename | test2.cpp:353:7:353:12 | call to access | checked |
| test2.cpp:369:7:369:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:369:13:369:16 | path | filename | test2.cpp:365:6:365:11 | call to access | checked |
| test2.cpp:400:3:400:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:400:9:400:12 | path | filename | test2.cpp:393:6:393:10 | call to fopen | checked |
| test2.cpp:408:3:408:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:408:9:408:13 | path2 | filename | test2.cpp:406:7:406:12 | call to rename | checked |

View File

@@ -199,6 +199,58 @@ void test2_10(int dir, const char *path, int arg)
// ...
}
void test2_11(const char *path, int arg)
{
stat_data buf;
int f;
if (stat(path, &buf))
{
f = open(path, arg); // GOOD (here stat is just a redundant check that the file exists / path is valid, confirmed by the return value of open) [FALSE POSITIVE]
if (f == -1)
{
// handle error
}
// ...
}
}
void test2_12(const char *path, int arg)
{
stat_data buf;
int f;
if (stat(path, &buf))
{
if (buf.foo == 11) // check a property of the file
{
f = open(path, arg); // BAD
if (f == -1)
{
// handle error
}
}
// ...
}
}
void test2_13(const char *path, int arg)
{
stat_data buf;
FILE *f;
if (stat(path, &buf)) // check the file does *not* exist
{
return;
}
f = fopen(path, "wt"); // BAD
// ...
}
// --- open -> stat ---
void test3_1(const char *path, int arg)

View File

@@ -492,8 +492,18 @@ namespace Semmle.Extraction.CSharp
/// <summary>
/// Gets a list of all `csharp.{hash}.txt` files currently written to the log directory.
/// </summary>
public static IEnumerable<string> GetCSharpArgsLogs() =>
Directory.EnumerateFiles(GetCSharpLogDirectory(), "csharp.*.txt");
public static IEnumerable<string> GetCSharpArgsLogs()
{
try
{
return Directory.EnumerateFiles(GetCSharpLogDirectory(), "csharp.*.txt");
}
catch (DirectoryNotFoundException)
{
// If the directory does not exist, there are no log files
return Enumerable.Empty<string>();
}
}
private static string GetCSharpLogDirectory()
{

View File

@@ -1,4 +1,4 @@
name: codeql-csharp-examples
name: codeql/csharp-examples
version: 0.0.2
dependencies:
codeql/csharp-all: "*"

View File

@@ -8,7 +8,7 @@ import csharp
* A `Web.config` file.
*/
class WebConfigXML extends XMLFile {
WebConfigXML() { getName().matches("%Web.config") }
WebConfigXML() { this.getName().matches("%Web.config") }
}
/** A `<configuration>` tag in an ASP.NET configuration file. */
@@ -73,12 +73,14 @@ class FormsElement extends XMLElement {
/**
* Gets attribute's `requireSSL` value.
*/
string getRequireSSL() { result = getAttribute("requireSSL").getValue().trim().toLowerCase() }
string getRequireSSL() {
result = this.getAttribute("requireSSL").getValue().trim().toLowerCase()
}
/**
* Holds if `requireSSL` value is true.
*/
predicate isRequireSSL() { getRequireSSL() = "true" }
predicate isRequireSSL() { this.getRequireSSL() = "true" }
}
/** A `<httpCookies>` tag in an ASP.NET configuration file. */
@@ -89,26 +91,28 @@ class HttpCookiesElement extends XMLElement {
* Gets attribute's `httpOnlyCookies` value.
*/
string getHttpOnlyCookies() {
result = getAttribute("httpOnlyCookies").getValue().trim().toLowerCase()
result = this.getAttribute("httpOnlyCookies").getValue().trim().toLowerCase()
}
/**
* Holds if there is any chance that `httpOnlyCookies` is set to `true`.
*/
predicate isHttpOnlyCookies() { getHttpOnlyCookies() = "true" }
predicate isHttpOnlyCookies() { this.getHttpOnlyCookies() = "true" }
/**
* Gets attribute's `requireSSL` value.
*/
string getRequireSSL() { result = getAttribute("requireSSL").getValue().trim().toLowerCase() }
string getRequireSSL() {
result = this.getAttribute("requireSSL").getValue().trim().toLowerCase()
}
/**
* Holds if there is any chance that `requireSSL` is set to `true` either globally or for Forms.
*/
predicate isRequireSSL() {
getRequireSSL() = "true"
this.getRequireSSL() = "true"
or
not getRequireSSL() = "false" and // not set all, i.e. default
exists(FormsElement forms | forms.getFile() = getFile() | forms.isRequireSSL())
not this.getRequireSSL() = "false" and // not set all, i.e. default
exists(FormsElement forms | forms.getFile() = this.getFile() | forms.isRequireSSL())
}
}

View File

@@ -20,7 +20,7 @@ class VariableAccess extends Access, @cil_access { }
/** An instruction that reads a variable. */
class ReadAccess extends VariableAccess, Expr, @cil_read_access {
override Type getType() { result = getTarget().getType() }
override Type getType() { result = this.getTarget().getType() }
}
/** An instruction yielding an address. */
@@ -49,7 +49,7 @@ class ParameterReadAccess extends ParameterAccess, ReadAccess {
class ParameterWriteAccess extends ParameterAccess, WriteAccess {
override int getPopCount() { result = 1 }
override Expr getExpr() { result = getOperand(0) }
override Expr getExpr() { result = this.getOperand(0) }
}
/** An access to the `this` parameter. */
@@ -71,9 +71,9 @@ class LocalVariableAccess extends StackVariableAccess, @cil_local_access {
class LocalVariableWriteAccess extends LocalVariableAccess, WriteAccess {
override int getPopCount() { result = 1 }
override Expr getExpr() { result = getOperand(0) }
override Expr getExpr() { result = this.getOperand(0) }
override string getExtra() { result = "L" + getTarget().getIndex() }
override string getExtra() { result = "L" + this.getTarget().getIndex() }
}
/** An instruction that reads a local variable. */
@@ -85,7 +85,7 @@ class LocalVariableReadAccess extends LocalVariableAccess, ReadAccess {
class FieldAccess extends VariableAccess, @cil_field_access {
override Field getTarget() { result = VariableAccess.super.getTarget() }
override string getExtra() { result = getTarget().getName() }
override string getExtra() { result = this.getTarget().getName() }
/** Gets the qualifier of the access, if any. */
abstract Expr getQualifier();

View File

@@ -10,7 +10,7 @@ private import CIL
*/
class BasicBlock extends Cached::TBasicBlockStart {
/** Gets an immediate successor of this basic block, if any. */
BasicBlock getASuccessor() { result.getFirstNode() = getLastNode().getASuccessor() }
BasicBlock getASuccessor() { result.getFirstNode() = this.getLastNode().getASuccessor() }
/** Gets an immediate predecessor of this basic block, if any. */
BasicBlock getAPredecessor() { result.getASuccessor() = this }
@@ -31,7 +31,7 @@ class BasicBlock extends Cached::TBasicBlockStart {
* The basic block on line 2 is an immediate `true` successor of the
* basic block on line 1.
*/
BasicBlock getATrueSuccessor() { result.getFirstNode() = getLastNode().getTrueSuccessor() }
BasicBlock getATrueSuccessor() { result.getFirstNode() = this.getLastNode().getTrueSuccessor() }
/**
* Gets an immediate `false` successor, if any.
@@ -49,22 +49,22 @@ class BasicBlock extends Cached::TBasicBlockStart {
* The basic block on line 2 is an immediate `false` successor of the
* basic block on line 1.
*/
BasicBlock getAFalseSuccessor() { result.getFirstNode() = getLastNode().getFalseSuccessor() }
BasicBlock getAFalseSuccessor() { result.getFirstNode() = this.getLastNode().getFalseSuccessor() }
/** Gets the control flow node at a specific (zero-indexed) position in this basic block. */
ControlFlowNode getNode(int pos) { Cached::bbIndex(getFirstNode(), result, pos) }
ControlFlowNode getNode(int pos) { Cached::bbIndex(this.getFirstNode(), result, pos) }
/** Gets a control flow node in this basic block. */
ControlFlowNode getANode() { result = getNode(_) }
ControlFlowNode getANode() { result = this.getNode(_) }
/** Gets the first control flow node in this basic block. */
ControlFlowNode getFirstNode() { this = Cached::TBasicBlockStart(result) }
/** Gets the last control flow node in this basic block. */
ControlFlowNode getLastNode() { result = getNode(length() - 1) }
ControlFlowNode getLastNode() { result = this.getNode(this.length() - 1) }
/** Gets the length of this basic block. */
int length() { result = strictcount(getANode()) }
int length() { result = strictcount(this.getANode()) }
/**
* Holds if this basic block strictly dominates basic block `bb`.
@@ -114,7 +114,7 @@ class BasicBlock extends Cached::TBasicBlockStart {
*/
predicate dominates(BasicBlock bb) {
bb = this or
strictlyDominates(bb)
this.strictlyDominates(bb)
}
/**
@@ -140,14 +140,14 @@ class BasicBlock extends Cached::TBasicBlockStart {
* does not dominate the basic block on line 6.
*/
predicate inDominanceFrontier(BasicBlock df) {
dominatesPredecessor(df) and
not strictlyDominates(df)
this.dominatesPredecessor(df) and
not this.strictlyDominates(df)
}
/**
* Holds if this basic block dominates a predecessor of `df`.
*/
private predicate dominatesPredecessor(BasicBlock df) { dominates(df.getAPredecessor()) }
private predicate dominatesPredecessor(BasicBlock df) { this.dominates(df.getAPredecessor()) }
/**
* Gets the basic block that immediately dominates this basic block, if any.
@@ -226,7 +226,7 @@ class BasicBlock extends Cached::TBasicBlockStart {
* post-dominates itself.
*/
predicate postDominates(BasicBlock bb) {
strictlyPostDominates(bb) or
this.strictlyPostDominates(bb) or
this = bb
}
@@ -239,7 +239,7 @@ class BasicBlock extends Cached::TBasicBlockStart {
predicate inLoop() { this.getASuccessor+() = this }
/** Gets a textual representation of this basic block. */
string toString() { result = getFirstNode().toString() }
string toString() { result = this.getFirstNode().toString() }
/** Gets the location of this basic block. */
Location getLocation() { result = this.getFirstNode().getLocation() }
@@ -325,16 +325,16 @@ private predicate exitBB(BasicBlock bb) { not exists(bb.getLastNode().getASucces
* A basic block with more than one predecessor.
*/
class JoinBlock extends BasicBlock {
JoinBlock() { getFirstNode().isJoin() }
JoinBlock() { this.getFirstNode().isJoin() }
}
/** A basic block that terminates in a condition, splitting the subsequent control flow. */
class ConditionBlock extends BasicBlock {
ConditionBlock() {
exists(BasicBlock succ |
succ = getATrueSuccessor()
succ = this.getATrueSuccessor()
or
succ = getAFalseSuccessor()
succ = this.getAFalseSuccessor()
)
}
@@ -380,16 +380,16 @@ class ConditionBlock extends BasicBlock {
*/
exists(BasicBlock succ |
isCandidateSuccessor(succ, testIsTrue) and
this.isCandidateSuccessor(succ, testIsTrue) and
succ.dominates(controlled)
)
}
private predicate isCandidateSuccessor(BasicBlock succ, boolean testIsTrue) {
(
testIsTrue = true and succ = getATrueSuccessor()
testIsTrue = true and succ = this.getATrueSuccessor()
or
testIsTrue = false and succ = getAFalseSuccessor()
testIsTrue = false and succ = this.getAFalseSuccessor()
) and
forall(BasicBlock pred | pred = succ.getAPredecessor() and pred != this | succ.dominates(pred))
}

View File

@@ -62,7 +62,7 @@ abstract class InstructionViolation extends CfgViolation, CfgCheck {
override string toString() {
result =
instruction.getImplementation().getMethod().toStringWithTypes() + ": " +
instruction.toString() + ", " + getInstructionsUpTo()
instruction.toString() + ", " + this.getInstructionsUpTo()
}
}
@@ -126,7 +126,7 @@ class MissingOperand extends InstructionViolation {
}
override string getMessage() {
result = "This instruction is missing operand " + getMissingOperand()
result = "This instruction is missing operand " + this.getMissingOperand()
}
}
@@ -364,7 +364,7 @@ class TypeViolation extends ConsistencyViolation, TypeCheck {
/** Gets the type containing the violation. */
Type getType() { this = TypeCheck(result) }
override string toString() { result = getType().toString() }
override string toString() { result = this.getType().toString() }
abstract override string getMessage();
}
@@ -374,7 +374,7 @@ class TypeViolation extends ConsistencyViolation, TypeCheck {
*/
class TypeIsBothConstructedAndUnbound extends TypeViolation {
TypeIsBothConstructedAndUnbound() {
getType() instanceof ConstructedGeneric and getType() instanceof UnboundGeneric
this.getType() instanceof ConstructedGeneric and this.getType() instanceof UnboundGeneric
}
override string getMessage() { result = "Type is both constructed and unbound" }
@@ -397,16 +397,16 @@ class InconsistentTypeLocation extends TypeViolation {
*/
class TypeParameterMismatch extends TypeViolation {
TypeParameterMismatch() {
getType().(ConstructedGeneric).getNumberOfTypeArguments() !=
getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters()
this.getType().(ConstructedGeneric).getNumberOfTypeArguments() !=
this.getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters()
}
override string getMessage() {
result =
"Constructed type (" + getType().toStringWithTypes() + ") has " +
getType().(ConstructedGeneric).getNumberOfTypeArguments() +
" type arguments and unbound type (" + getType().getUnboundType().toStringWithTypes() +
") has " + getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters() +
"Constructed type (" + this.getType().toStringWithTypes() + ") has " +
this.getType().(ConstructedGeneric).getNumberOfTypeArguments() +
" type arguments and unbound type (" + this.getType().getUnboundType().toStringWithTypes() +
") has " + this.getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters() +
" type parameters"
}
}
@@ -418,7 +418,7 @@ class MethodViolation extends ConsistencyViolation, DeclarationCheck {
/** Gets the method containing the violation. */
Method getMethod() { this = DeclarationCheck(result) }
override string toString() { result = getMethod().toString() }
override string toString() { result = this.getMethod().toString() }
override string getMessage() { none() }
}
@@ -440,14 +440,15 @@ class InconsistentMethodLocation extends MethodViolation {
*/
class ConstructedMethodTypeParams extends MethodViolation {
ConstructedMethodTypeParams() {
getMethod().(ConstructedGeneric).getNumberOfTypeArguments() !=
getMethod().getUnboundDeclaration().(UnboundGeneric).getNumberOfTypeParameters()
this.getMethod().(ConstructedGeneric).getNumberOfTypeArguments() !=
this.getMethod().getUnboundDeclaration().(UnboundGeneric).getNumberOfTypeParameters()
}
override string getMessage() {
result =
"The constructed method " + getMethod().toStringWithTypes() +
" does not match unbound method " + getMethod().getUnboundDeclaration().toStringWithTypes()
"The constructed method " + this.getMethod().toStringWithTypes() +
" does not match unbound method " +
this.getMethod().getUnboundDeclaration().toStringWithTypes()
}
}
@@ -477,8 +478,8 @@ class InvalidOverride extends MethodViolation {
private Method base;
InvalidOverride() {
base = getMethod().getOverriddenMethod() and
not getMethod().getDeclaringType().getABaseType+() = base.getDeclaringType() and
base = this.getMethod().getOverriddenMethod() and
not this.getMethod().getDeclaringType().getABaseType+() = base.getDeclaringType() and
base.getDeclaringType().isUnboundDeclaration() // Bases classes of constructed types aren't extracted properly.
}
@@ -493,7 +494,9 @@ class InvalidOverride extends MethodViolation {
* A pointer type that does not have a pointee type.
*/
class InvalidPointerType extends TypeViolation {
InvalidPointerType() { exists(PointerType p | p = getType() | count(p.getReferentType()) != 1) }
InvalidPointerType() {
exists(PointerType p | p = this.getType() | count(p.getReferentType()) != 1)
}
override string getMessage() { result = "Invalid Pointertype.getPointeeType()" }
}
@@ -502,7 +505,9 @@ class InvalidPointerType extends TypeViolation {
* An array with an invalid `getElementType`.
*/
class ArrayTypeMissingElement extends TypeViolation {
ArrayTypeMissingElement() { exists(ArrayType t | t = getType() | count(t.getElementType()) != 1) }
ArrayTypeMissingElement() {
exists(ArrayType t | t = this.getType() | count(t.getElementType()) != 1)
}
override string getMessage() { result = "Invalid ArrayType.getElementType()" }
}
@@ -511,7 +516,7 @@ class ArrayTypeMissingElement extends TypeViolation {
* An array with an invalid `getRank`.
*/
class ArrayTypeInvalidRank extends TypeViolation {
ArrayTypeInvalidRank() { exists(ArrayType t | t = getType() | not t.getRank() > 0) }
ArrayTypeInvalidRank() { exists(ArrayType t | t = this.getType() | not t.getRank() > 0) }
override string getMessage() { result = "Invalid ArrayType.getRank()" }
}
@@ -564,7 +569,7 @@ abstract class DeclarationViolation extends ConsistencyViolation, DeclarationChe
/** Gets the member containing the potential violation. */
Declaration getDeclaration() { this = DeclarationCheck(result) }
override string toString() { result = getDeclaration().toString() }
override string toString() { result = this.getDeclaration().toString() }
}
/**
@@ -572,7 +577,7 @@ abstract class DeclarationViolation extends ConsistencyViolation, DeclarationChe
*/
class PropertyWithNoAccessors extends DeclarationViolation {
PropertyWithNoAccessors() {
exists(Property p | p = getDeclaration() | not exists(p.getAnAccessor()))
exists(Property p | p = this.getDeclaration() | not exists(p.getAnAccessor()))
}
override string getMessage() { result = "Property has no accessors" }
@@ -646,7 +651,7 @@ class TypeMultiplyDefined extends TypeViolation, DisabledCheck {
override string getMessage() {
result =
"This type (" + getType().toStringWithTypes() + ") has " +
"This type (" + this.getType().toStringWithTypes() + ") has " +
count(Type t |
not t instanceof ConstructedGeneric and
t.toStringWithTypes() = this.getType().toStringWithTypes()
@@ -669,11 +674,11 @@ class MissingCilDeclaration extends ConsistencyViolation, MissingCSharpCheck {
override string getMessage() {
result =
"Cannot locate CIL for " + getDeclaration().toStringWithTypes() + " of class " +
getDeclaration().getPrimaryQlClasses()
"Cannot locate CIL for " + this.getDeclaration().toStringWithTypes() + " of class " +
this.getDeclaration().getPrimaryQlClasses()
}
override string toString() { result = getDeclaration().toStringWithTypes() }
override string toString() { result = this.getDeclaration().toStringWithTypes() }
}
/**
@@ -717,21 +722,23 @@ private predicate expectedCilDeclaration(CS::Declaration decl) {
/** A member with an invalid name. */
class MemberWithInvalidName extends DeclarationViolation {
MemberWithInvalidName() {
exists(string name | name = getDeclaration().(Member).getName() |
exists(string name | name = this.getDeclaration().(Member).getName() |
exists(name.indexOf(".")) and
not name = ".ctor" and
not name = ".cctor"
)
}
override string getMessage() { result = "Invalid name " + getDeclaration().(Member).getName() }
override string getMessage() {
result = "Invalid name " + this.getDeclaration().(Member).getName()
}
}
class ConstructedSourceDeclarationMethod extends MethodViolation {
Method method;
ConstructedSourceDeclarationMethod() {
method = getMethod() and
method = this.getMethod() and
method = method.getUnboundDeclaration() and
(
method instanceof ConstructedGeneric or
@@ -751,7 +758,7 @@ class DeclarationWithMultipleLabels extends DeclarationViolation {
}
override string getMessage() {
result = "Multiple labels " + concat(getDeclaration().getLabel(), ", ")
result = "Multiple labels " + concat(this.getDeclaration().getLabel(), ", ")
}
}

View File

@@ -23,13 +23,13 @@ class ControlFlowNode extends @cil_controlflow_node {
int getPopCount() { result = 0 }
/** Gets a successor of this node, if any. */
final Instruction getASuccessor() { result = getASuccessorType(_) }
final Instruction getASuccessor() { result = this.getASuccessorType(_) }
/** Gets a true successor of this node, if any. */
final Instruction getTrueSuccessor() { result = getASuccessorType(any(TrueFlow f)) }
final Instruction getTrueSuccessor() { result = this.getASuccessorType(any(TrueFlow f)) }
/** Gets a false successor of this node, if any. */
final Instruction getFalseSuccessor() { result = getASuccessorType(any(FalseFlow f)) }
final Instruction getFalseSuccessor() { result = this.getASuccessorType(any(FalseFlow f)) }
/** Gets a successor to this node, of type `type`, if any. */
cached
@@ -57,7 +57,7 @@ class ControlFlowNode extends @cil_controlflow_node {
}
/** Gets an operand of this instruction, if any. */
ControlFlowNode getAnOperand() { result = getOperand(_) }
ControlFlowNode getAnOperand() { result = this.getOperand(_) }
/** Gets an expression that consumes the output of this instruction on the stack. */
Instruction getParentExpr() { this = result.getAnOperand() }
@@ -86,17 +86,17 @@ class ControlFlowNode extends @cil_controlflow_node {
)
}
private int getStackDelta() { result = getPushCount() - getPopCount() }
private int getStackDelta() { result = this.getPushCount() - this.getPopCount() }
/** Gets the stack size before this instruction. */
int getStackSizeBefore() { result = getAPredecessor().getStackSizeAfter() }
int getStackSizeBefore() { result = this.getAPredecessor().getStackSizeAfter() }
/** Gets the stack size after this instruction. */
final int getStackSizeAfter() {
// This is a guard to prevent ill formed programs
// and other logic errors going into an infinite loop.
result in [0 .. getImplementation().getStackSize()] and
result = getStackSizeBefore() + getStackDelta()
result in [0 .. this.getImplementation().getStackSize()] and
result = this.getStackSizeBefore() + this.getStackDelta()
}
/** Gets the method containing this control flow node. */

View File

@@ -68,7 +68,7 @@ class Member extends DotNet::Member, Declaration, @cil_member {
/** Holds if this member has a security attribute. */
predicate hasSecurity() { cil_security(this) }
override Location getLocation() { result = getDeclaringType().getLocation() }
override Location getLocation() { result = this.getDeclaringType().getLocation() }
}
/** A property. */
@@ -87,24 +87,25 @@ class Property extends DotNet::Property, Member, CustomModifierReceiver, @cil_pr
override Setter getSetter() { this = result.getProperty() }
/** Gets an accessor of this property. */
Accessor getAnAccessor() { result = getGetter() or result = getSetter() }
Accessor getAnAccessor() { result = this.getGetter() or result = this.getSetter() }
override string toString() { result = "property " + getName() }
override string toString() { result = "property " + this.getName() }
override string toStringWithTypes() {
result =
getType().toStringWithTypes() + " " + getDeclaringType().toStringWithTypes() + "." + getName()
this.getType().toStringWithTypes() + " " + this.getDeclaringType().toStringWithTypes() + "." +
this.getName()
}
}
/** A property that is trivial (wraps a field). */
class TrivialProperty extends Property {
TrivialProperty() {
getGetter().(TrivialGetter).getField() = getSetter().(TrivialSetter).getField()
this.getGetter().(TrivialGetter).getField() = this.getSetter().(TrivialSetter).getField()
}
/** Gets the underlying field of this property. */
Field getField() { result = getGetter().(TrivialGetter).getField() }
Field getField() { result = this.getGetter().(TrivialGetter).getField() }
}
/** An event. */
@@ -125,9 +126,9 @@ class Event extends DotNet::Event, Member, @cil_event {
/** Gets the raiser. */
Method getRaiser() { cil_raiser(this, result) }
override string toString() { result = "event " + getName() }
override string toString() { result = "event " + this.getName() }
override string toStringWithTypes() {
result = getDeclaringType().toStringWithTypes() + "." + getName()
result = this.getDeclaringType().toStringWithTypes() + "." + this.getName()
}
}

View File

@@ -45,5 +45,5 @@ class ConstructedType extends ConstructedGeneric, Type {
/** A constructed generic method. */
class ConstructedMethod extends ConstructedGeneric, Method {
final override UnboundGenericMethod getUnboundGeneric() { result = getUnboundMethod() }
final override UnboundGenericMethod getUnboundGeneric() { result = this.getUnboundMethod() }
}

View File

@@ -4,15 +4,17 @@ private import CIL
/** An instruction. */
class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instruction {
override string toString() { result = getOpcodeName() }
override string toString() { result = this.getOpcodeName() }
/** Gets a more verbose textual representation of this instruction. */
string toStringExtra() { result = getIndex() + ": " + getOpcodeName() + getExtraStr() }
string toStringExtra() {
result = this.getIndex() + ": " + this.getOpcodeName() + this.getExtraStr()
}
/** Gets the method containing this instruction. */
override MethodImplementation getImplementation() { cil_instruction(this, _, _, result) }
override Method getMethod() { result = getImplementation().getMethod() }
override Method getMethod() { result = this.getImplementation().getMethod() }
/**
* Gets the index of this instruction.
@@ -30,7 +32,7 @@ class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instructi
string getExtra() { none() }
private string getExtraStr() {
if exists(getExtra()) then result = " " + getExtra() else result = ""
if exists(this.getExtra()) then result = " " + this.getExtra() else result = ""
}
/** Gets the declaration accessed by this instruction, if any. */
@@ -39,8 +41,8 @@ class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instructi
/** Gets a successor instruction to this instruction. */
override Instruction getASuccessorType(FlowType t) {
t instanceof NormalFlow and
canFlowNext() and
result = this.getImplementation().getInstruction(getIndex() + 1)
this.canFlowNext() and
result = this.getImplementation().getInstruction(this.getIndex() + 1)
}
/** Holds if this instruction passes control flow into the next instruction. */
@@ -61,7 +63,7 @@ class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instructi
override Location getALocation() {
cil_instruction_location(this, result) // The source code, if available
or
result = getImplementation().getLocation() // The containing assembly
result = this.getImplementation().getLocation() // The containing assembly
}
override Location getLocation() { result = Element.super.getLocation() }

View File

@@ -14,7 +14,7 @@ class Expr extends DotNet::Expr, Instruction, @cil_expr {
override Type getType() { result = Instruction.super.getType() }
override Method getEnclosingCallable() { result = getImplementation().getMethod() }
override Method getEnclosingCallable() { result = this.getImplementation().getMethod() }
/**
* The "parent" of a CIL expression is taken to be the instruction
@@ -28,13 +28,13 @@ class Branch extends Instruction, @cil_jump {
/** Gets the instruction that is jumped to. */
Instruction getTarget() { cil_jump(this, result) }
override string getExtra() { result = getTarget().getIndex() + ":" }
override string getExtra() { result = this.getTarget().getIndex() + ":" }
}
/** An instruction that unconditionally jumps to another instruction. */
class UnconditionalBranch extends Branch, @cil_unconditional_jump {
override Instruction getASuccessorType(FlowType t) {
t instanceof NormalFlow and result = getTarget()
t instanceof NormalFlow and result = this.getTarget()
}
override predicate canFlowNext() { none() }
@@ -43,9 +43,9 @@ class UnconditionalBranch extends Branch, @cil_unconditional_jump {
/** An instruction that jumps to a target based on a condition. */
class ConditionalBranch extends Branch, @cil_conditional_jump {
override Instruction getASuccessorType(FlowType t) {
t instanceof TrueFlow and result = getTarget()
t instanceof TrueFlow and result = this.getTarget()
or
t instanceof FalseFlow and result = getImplementation().getInstruction(getIndex() + 1)
t instanceof FalseFlow and result = this.getImplementation().getInstruction(this.getIndex() + 1)
}
override int getPushCount() { result = 0 }
@@ -61,7 +61,7 @@ class UnaryExpr extends Expr, @cil_unary_expr {
override int getPopCount() { result = 1 }
/** Gets the operand of this unary expression. */
Expr getOperand() { result = getOperand(0) }
Expr getOperand() { result = this.getOperand(0) }
}
/** A binary expression that compares two values. */
@@ -73,8 +73,8 @@ class ComparisonOperation extends BinaryExpr, @cil_comparison_operation {
class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation {
override Type getType() {
exists(Type t0, Type t1 |
t0 = getOperand(0).getType().getUnderlyingType() and
t1 = getOperand(1).getType().getUnderlyingType()
t0 = this.getOperand(0).getType().getUnderlyingType() and
t1 = this.getOperand(1).getType().getUnderlyingType()
|
t0 = t1 and result = t0
or
@@ -100,7 +100,7 @@ class UnaryBitwiseOperation extends UnaryExpr, @cil_unary_bitwise_operation {
/** A unary expression that converts a value from one primitive type to another. */
class Conversion extends UnaryExpr, @cil_conversion_operation {
/** Gets the expression being converted. */
Expr getExpr() { result = getOperand(0) }
Expr getExpr() { result = this.getOperand(0) }
}
/** A branch that leaves the scope of a `Handler`. */
@@ -111,7 +111,7 @@ class Literal extends DotNet::Literal, Expr, @cil_literal {
/** Gets the pushed value. */
override string getValue() { cil_value(this, result) }
override string getExtra() { result = getValue() }
override string getExtra() { result = this.getValue() }
}
/** An integer literal. */
@@ -149,44 +149,44 @@ class Call extends Expr, DotNet::Call, @cil_call_any {
/** Gets the method that is called. */
override Method getTarget() { cil_access(this, result) }
override Method getARuntimeTarget() { result = getTarget().getAnOverrider*() }
override Method getARuntimeTarget() { result = this.getTarget().getAnOverrider*() }
override string getExtra() { result = getTarget().getQualifiedName() }
override string getExtra() { result = this.getTarget().getQualifiedName() }
/**
* Gets the return type of the call. Methods that do not return a value
* return the `void` type, `System.Void`, although the value of `getPushCount` is
* 0 in this case.
*/
override Type getType() { result = getTarget().getReturnType() }
override Type getType() { result = this.getTarget().getReturnType() }
// The number of items popped/pushed from the stack
// depends on the target of the call.
override int getPopCount() { result = getTarget().getCallPopCount() }
override int getPopCount() { result = this.getTarget().getCallPopCount() }
override int getPushCount() { result = getTarget().getCallPushCount() }
override int getPushCount() { result = this.getTarget().getCallPushCount() }
/**
* Holds if this is a "tail call", meaning that control does not return to the
* calling method.
*/
predicate isTailCall() {
getImplementation().getInstruction(getIndex() - 1) instanceof Opcodes::Tail
this.getImplementation().getInstruction(this.getIndex() - 1) instanceof Opcodes::Tail
}
/** Holds if this call is virtual and could go to an overriding method. */
predicate isVirtual() { none() }
override Expr getRawArgument(int i) { result = getOperand(getPopCount() - i - 1) }
override Expr getRawArgument(int i) { result = this.getOperand(this.getPopCount() - i - 1) }
/** Gets the qualifier of this call, if any. */
Expr getQualifier() { result = getRawArgument(0) and not getTarget().isStatic() }
Expr getQualifier() { result = this.getRawArgument(0) and not this.getTarget().isStatic() }
override Expr getArgument(int i) {
if getTarget().isStatic()
then result = getRawArgument(i)
if this.getTarget().isStatic()
then result = this.getRawArgument(i)
else (
result = getRawArgument(i + 1) and i >= 0
result = this.getRawArgument(i + 1) and i >= 0
)
}
@@ -217,10 +217,10 @@ class VirtualCall extends Call {
/** A read of an array element. */
class ReadArrayElement extends BinaryExpr, @cil_read_array {
/** Gets the array being read. */
Expr getArray() { result = getOperand(1) }
Expr getArray() { result = this.getOperand(1) }
/** Gets the index into the array. */
Expr getArrayIndex() { result = getOperand(0) }
Expr getArrayIndex() { result = this.getOperand(0) }
}
/** A write of an array element. */
@@ -233,14 +233,14 @@ class WriteArrayElement extends Instruction, @cil_write_array {
/** A `return` statement. */
class Return extends Instruction, @cil_ret {
/** Gets the expression being returned, if any. */
Expr getExpr() { result = getOperand(0) }
Expr getExpr() { result = this.getOperand(0) }
override predicate canFlowNext() { none() }
}
/** A `throw` statement. */
class Throw extends Instruction, DotNet::Throw, @cil_throw_any {
override Expr getExpr() { result = getOperand(0) }
override Expr getExpr() { result = this.getOperand(0) }
override predicate canFlowNext() { none() }
}
@@ -250,10 +250,10 @@ class StoreIndirect extends Instruction, @cil_stind {
override int getPopCount() { result = 2 }
/** Gets the location to store the value at. */
Expr getAddress() { result = getOperand(1) }
Expr getAddress() { result = this.getOperand(1) }
/** Gets the value to store. */
Expr getExpr() { result = getOperand(0) }
Expr getExpr() { result = this.getOperand(0) }
}
/** Loads a value from an address/location. */

View File

@@ -83,21 +83,21 @@ module Opcodes {
class Ldc_i4 extends IntLiteral, @cil_ldc_i4 {
override string getOpcodeName() { result = "ldc.i4" }
override string getExtra() { result = getValue() }
override string getExtra() { result = this.getValue() }
}
/** An `ldc.i8` instruction. */
class Ldc_i8 extends IntLiteral, @cil_ldc_i8 {
override string getOpcodeName() { result = "ldc.i8" }
override string getExtra() { result = getValue() }
override string getExtra() { result = this.getValue() }
}
/** An `ldc.i4.s` instruction. */
class Ldc_i4_s extends IntLiteral, @cil_ldc_i4_s {
override string getOpcodeName() { result = "ldc.i4.s" }
override string getExtra() { result = getValue() }
override string getExtra() { result = this.getValue() }
}
/** An `ldnull` instruction. */
@@ -115,7 +115,7 @@ module Opcodes {
class Ldc_r4 extends FloatLiteral, @cil_ldc_r4 {
override string getOpcodeName() { result = "ldc.r4" }
override string getExtra() { result = getValue() }
override string getExtra() { result = this.getValue() }
override Type getType() { result instanceof FloatType }
}
@@ -124,7 +124,7 @@ module Opcodes {
class Ldc_r8 extends FloatLiteral, @cil_ldc_r8 {
override string getOpcodeName() { result = "ldc.r8" }
override string getExtra() { result = getValue() }
override string getExtra() { result = this.getValue() }
override Type getType() { result instanceof DoubleType }
}
@@ -199,9 +199,9 @@ module Opcodes {
override string getOpcodeName() { result = "neg" }
override NumericType getType() {
result = getOperand().getType()
result = this.getOperand().getType()
or
getOperand().getType() instanceof Enum and result instanceof IntType
this.getOperand().getType() instanceof Enum and result instanceof IntType
}
}
@@ -260,7 +260,7 @@ module Opcodes {
override int getPushCount() { result = 2 } // This is the only instruction that pushes 2 items
override Type getType() { result = getOperand(0).getType() }
override Type getType() { result = this.getOperand(0).getType() }
}
/** A `ret` instruction. */
@@ -270,7 +270,7 @@ module Opcodes {
override predicate canFlowNext() { none() }
override int getPopCount() {
if getImplementation().getMethod().returnsVoid() then result = 0 else result = 1
if this.getImplementation().getMethod().returnsVoid() then result = 0 else result = 1
}
}
@@ -283,7 +283,7 @@ module Opcodes {
class Ldstr extends StringLiteral, @cil_ldstr {
override string getOpcodeName() { result = "ldstr" }
override string getExtra() { result = "\"" + getValue() + "\"" }
override string getExtra() { result = "\"" + this.getValue() + "\"" }
override Type getType() { result instanceof StringType }
}
@@ -427,11 +427,14 @@ module Opcodes {
override Instruction getASuccessorType(FlowType t) {
t instanceof NormalFlow and
(result = getTarget(_) or result = getImplementation().getInstruction(getIndex() + 1))
(
result = this.getTarget(_) or
result = this.getImplementation().getInstruction(this.getIndex() + 1)
)
}
override string getExtra() {
result = concat(int n | exists(getTarget(n)) | getTarget(n).getIndex() + ":", " ")
result = concat(int n | exists(this.getTarget(n)) | this.getTarget(n).getIndex() + ":", " ")
}
}
@@ -493,9 +496,9 @@ module Opcodes {
// The number of items popped/pushed from the stack depends on the target of
// the call. Also, we need to pop the function pointer itself too.
override int getPopCount() { result = getTargetType().getCallPopCount() + 1 }
override int getPopCount() { result = this.getTargetType().getCallPopCount() + 1 }
override int getPushCount() { result = getTargetType().getCallPushCount() }
override int getPushCount() { result = this.getTargetType().getCallPushCount() }
}
/** A `callvirt` instruction. */
@@ -524,49 +527,49 @@ module Opcodes {
override BoolType getType() { exists(result) }
/** Gets the type that is being tested against. */
Type getTestedType() { result = getAccess() }
Type getTestedType() { result = this.getAccess() }
override string getExtra() { result = getTestedType().getQualifiedName() }
override string getExtra() { result = this.getTestedType().getQualifiedName() }
}
/** A `castclass` instruction. */
class Castclass extends UnaryExpr, @cil_castclass {
override string getOpcodeName() { result = "castclass" }
override Type getType() { result = getAccess() }
override Type getType() { result = this.getAccess() }
/** Gets the type that is being cast to. */
Type getTestedType() { result = getAccess() }
Type getTestedType() { result = this.getAccess() }
override string getExtra() { result = getTestedType().getQualifiedName() }
override string getExtra() { result = this.getTestedType().getQualifiedName() }
}
/** An `stloc.0` instruction. */
class Stloc_0 extends LocalVariableWriteAccess, @cil_stloc_0 {
override string getOpcodeName() { result = "stloc.0" }
override LocalVariable getTarget() { result = getImplementation().getLocalVariable(0) }
override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(0) }
}
/** An `stloc.1` instruction. */
class Stloc_1 extends LocalVariableWriteAccess, @cil_stloc_1 {
override string getOpcodeName() { result = "stloc.1" }
override LocalVariable getTarget() { result = getImplementation().getLocalVariable(1) }
override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(1) }
}
/** An `stloc.2` instruction. */
class Stloc_2 extends LocalVariableWriteAccess, @cil_stloc_2 {
override string getOpcodeName() { result = "stloc.2" }
override LocalVariable getTarget() { result = getImplementation().getLocalVariable(2) }
override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(2) }
}
/** An `stloc.3` instruction. */
class Stloc_3 extends LocalVariableWriteAccess, @cil_stloc_3 {
override string getOpcodeName() { result = "stloc.3" }
override LocalVariable getTarget() { result = getImplementation().getLocalVariable(3) }
override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(3) }
}
/** An `stloc.s` instruction. */
@@ -587,28 +590,28 @@ module Opcodes {
class Ldloc_0 extends LocalVariableReadAccess, @cil_ldloc_0 {
override string getOpcodeName() { result = "ldloc.0" }
override LocalVariable getTarget() { result = getImplementation().getLocalVariable(0) }
override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(0) }
}
/** An `ldloc.1` instruction. */
class Ldloc_1 extends LocalVariableReadAccess, @cil_ldloc_1 {
override string getOpcodeName() { result = "ldloc.1" }
override LocalVariable getTarget() { result = getImplementation().getLocalVariable(1) }
override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(1) }
}
/** An `ldloc.2` instruction. */
class Ldloc_2 extends LocalVariableReadAccess, @cil_ldloc_2 {
override string getOpcodeName() { result = "ldloc.2" }
override LocalVariable getTarget() { result = getImplementation().getLocalVariable(2) }
override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(2) }
}
/** An `ldloc.3` instruction. */
class Ldloc_3 extends LocalVariableReadAccess, @cil_ldloc_3 {
override string getOpcodeName() { result = "ldloc.3" }
override LocalVariable getTarget() { result = getImplementation().getLocalVariable(3) }
override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(3) }
}
/** An `ldloc.s` instruction. */
@@ -617,7 +620,7 @@ module Opcodes {
override LocalVariable getTarget() { cil_access(this, result) }
override string getExtra() { result = "L" + getTarget().getIndex() }
override string getExtra() { result = "L" + this.getTarget().getIndex() }
}
/** An `ldloca.s` instruction. */
@@ -626,7 +629,7 @@ module Opcodes {
override LocalVariable getTarget() { cil_access(this, result) }
override string getExtra() { result = "L" + getTarget().getIndex() }
override string getExtra() { result = "L" + this.getTarget().getIndex() }
}
/** An `ldloc` instruction. */
@@ -635,7 +638,7 @@ module Opcodes {
override LocalVariable getTarget() { cil_access(this, result) }
override string getExtra() { result = "L" + getTarget().getIndex() }
override string getExtra() { result = "L" + this.getTarget().getIndex() }
}
/** An `ldarg.0` instruction. */
@@ -643,7 +646,7 @@ module Opcodes {
override string getOpcodeName() { result = "ldarg.0" }
override MethodParameter getTarget() {
result = getImplementation().getMethod().getRawParameter(0)
result = this.getImplementation().getMethod().getRawParameter(0)
}
}
@@ -652,7 +655,7 @@ module Opcodes {
override string getOpcodeName() { result = "ldarg.1" }
override MethodParameter getTarget() {
result = getImplementation().getMethod().getRawParameter(1)
result = this.getImplementation().getMethod().getRawParameter(1)
}
}
@@ -661,7 +664,7 @@ module Opcodes {
override string getOpcodeName() { result = "ldarg.2" }
override MethodParameter getTarget() {
result = getImplementation().getMethod().getRawParameter(2)
result = this.getImplementation().getMethod().getRawParameter(2)
}
}
@@ -670,7 +673,7 @@ module Opcodes {
override string getOpcodeName() { result = "ldarg.3" }
override MethodParameter getTarget() {
result = getImplementation().getMethod().getRawParameter(3)
result = this.getImplementation().getMethod().getRawParameter(3)
}
}
@@ -710,7 +713,7 @@ module Opcodes {
override int getPopCount() { result = 1 }
override Expr getQualifier() { result = getOperand(0) }
override Expr getQualifier() { result = this.getOperand(0) }
}
/** An `ldflda` instruction. */
@@ -719,7 +722,7 @@ module Opcodes {
override int getPopCount() { result = 1 }
override Expr getQualifier() { result = getOperand(0) }
override Expr getQualifier() { result = this.getOperand(0) }
}
/** An `ldsfld` instruction. */
@@ -746,9 +749,9 @@ module Opcodes {
override int getPopCount() { result = 2 }
override Expr getQualifier() { result = getOperand(1) }
override Expr getQualifier() { result = this.getOperand(1) }
override Expr getExpr() { result = getOperand(0) }
override Expr getExpr() { result = this.getOperand(0) }
}
/** An `stsfld` instruction. */
@@ -759,7 +762,7 @@ module Opcodes {
override Expr getQualifier() { none() }
override Expr getExpr() { result = getOperand(0) }
override Expr getExpr() { result = this.getOperand(0) }
}
/** A `newobj` instruction. */
@@ -772,7 +775,7 @@ module Opcodes {
override Type getType() { result = this.getTarget().getDeclaringType() }
override Expr getArgument(int i) { result = getRawArgument(i) }
override Expr getArgument(int i) { result = this.getRawArgument(i) }
pragma[noinline]
private Parameter getARawTargetParameter() { result = this.getTarget().getARawParameter() }
@@ -796,21 +799,21 @@ module Opcodes {
class Box extends UnaryExpr, @cil_box {
override string getOpcodeName() { result = "box" }
override Type getType() { result = getAccess() }
override Type getType() { result = this.getAccess() }
}
/** An `unbox.any` instruction. */
class Unbox_any extends UnaryExpr, @cil_unbox_any {
override string getOpcodeName() { result = "unbox.any" }
override Type getType() { result = getAccess() }
override Type getType() { result = this.getAccess() }
}
/** An `unbox` instruction. */
class Unbox extends UnaryExpr, @cil_unbox {
override string getOpcodeName() { result = "unbox" }
override Type getType() { result = getAccess() }
override Type getType() { result = this.getAccess() }
}
/** An `ldobj` instruction. */
@@ -820,7 +823,7 @@ module Opcodes {
/** Gets the type of the object. */
Type getTarget() { cil_access(this, result) }
override Type getType() { result = getAccess() }
override Type getType() { result = this.getAccess() }
}
/** An `ldtoken` instruction. */
@@ -867,31 +870,31 @@ module Opcodes {
// Note that this is technically wrong - it should be
// result.(ArrayType).getElementType() = getAccess()
// However the (ArrayType) may not be in the database.
result = getAccess()
result = this.getAccess()
}
override string getExtra() { result = getType().getQualifiedName() }
override string getExtra() { result = this.getType().getQualifiedName() }
}
/** An `ldelem` instruction. */
class Ldelem extends ReadArrayElement, @cil_ldelem {
override string getOpcodeName() { result = "ldelem" }
override Type getType() { result = getAccess() }
override Type getType() { result = this.getAccess() }
}
/** An `ldelem.ref` instruction. */
class Ldelem_ref extends ReadArrayElement, @cil_ldelem_ref {
override string getOpcodeName() { result = "ldelem.ref" }
override Type getType() { result = getArray().getType() }
override Type getType() { result = this.getArray().getType() }
}
/** An `ldelema` instruction. */
class Ldelema extends ReadArrayElement, ReadRef, @cil_ldelema {
override string getOpcodeName() { result = "ldelema" }
override Type getType() { result = getAccess() }
override Type getType() { result = this.getAccess() }
}
/** An `stelem.ref` instruction. */
@@ -1410,7 +1413,7 @@ module Opcodes {
override int getPopCount() { result = 1 }
override Type getType() { result = getAccess() }
override Type getType() { result = this.getAccess() }
}
/** A `refanytype` instruction. */

View File

@@ -28,13 +28,13 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation {
LocalVariable getLocalVariable(int n) { cil_local_variable(result, this, n, _) }
/** Gets a local variable of this implementation, if any. */
LocalVariable getALocalVariable() { result = getLocalVariable(_) }
LocalVariable getALocalVariable() { result = this.getLocalVariable(_) }
/** Gets an instruction in this implementation, if any. */
Instruction getAnInstruction() { result = getInstruction(_) }
Instruction getAnInstruction() { result = this.getInstruction(_) }
/** Gets the total number of instructions in this implementation. */
int getNumberOfInstructions() { result = count(getAnInstruction()) }
int getNumberOfInstructions() { result = count(this.getAnInstruction()) }
/** Gets the `i`th handler in this implementation. */
Handler getHandler(int i) { result.getImplementation() = this and result.getIndex() = i }
@@ -49,7 +49,7 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation {
/** Gets the maximum stack size of this implementation. */
int getStackSize() { cil_method_stack_size(this, result) }
override string toString() { result = getMethod().toString() }
override string toString() { result = this.getMethod().toString() }
/** Gets a string representing the disassembly of this implementation. */
string getDisassembly() {
@@ -75,13 +75,13 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN
MethodImplementation getAnImplementation() { result.getMethod() = this }
/** Gets the "best" implementation of this method, if any. */
BestImplementation getImplementation() { result = getAnImplementation() }
BestImplementation getImplementation() { result = this.getAnImplementation() }
override Method getMethod() { result = this }
override string getName() { cil_method(this, result, _, _) }
override string getUndecoratedName() { result = getName() }
override string getUndecoratedName() { result = this.getName() }
override string toString() { result = this.getName() }
@@ -92,25 +92,29 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN
override Location getALocation() { cil_method_location(this.getUnboundDeclaration(), result) }
override MethodParameter getParameter(int n) {
if isStatic() then result = getRawParameter(n) else (result = getRawParameter(n + 1) and n >= 0)
if this.isStatic()
then result = this.getRawParameter(n)
else (
result = this.getRawParameter(n + 1) and n >= 0
)
}
override Type getType() { result = getReturnType() }
override Type getType() { result = this.getReturnType() }
/** Gets the return type of this method. */
override Type getReturnType() { cil_method(this, _, _, result) }
/** Holds if the return type is `void`. */
predicate returnsVoid() { getReturnType() instanceof VoidType }
predicate returnsVoid() { this.getReturnType() instanceof VoidType }
/** Gets the number of stack items pushed in a call to this method. */
int getCallPushCount() { if returnsVoid() then result = 0 else result = 1 }
int getCallPushCount() { if this.returnsVoid() then result = 0 else result = 1 }
/** Gets the number of stack items popped in a call to this method. */
int getCallPopCount() { result = count(getRawParameter(_)) }
int getCallPopCount() { result = count(this.getRawParameter(_)) }
/** Gets a method called by this method. */
Method getACallee() { result = getImplementation().getAnInstruction().(Call).getTarget() }
Method getACallee() { result = this.getImplementation().getAnInstruction().(Call).getTarget() }
/** Holds if this method is `virtual`. */
predicate isVirtual() { cil_virtual(this) }
@@ -129,43 +133,45 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN
/** Gets the unbound declaration of this method, or the method itself. */
Method getUnboundMethod() { cil_method_source_declaration(this, result) }
override Method getUnboundDeclaration() { result = getUnboundMethod() }
override Method getUnboundDeclaration() { result = this.getUnboundMethod() }
/** Holds if this method is an instance constructor. */
predicate isInstanceConstructor() { isSpecial() and getName() = ".ctor" }
predicate isInstanceConstructor() { this.isSpecial() and this.getName() = ".ctor" }
/** Holds if this method is a static class constructor. */
predicate isStaticConstructor() { isSpecial() and getName() = ".cctor" }
predicate isStaticConstructor() { this.isSpecial() and this.getName() = ".cctor" }
/** Holds if this method is a constructor (static or instance). */
predicate isConstructor() { isStaticConstructor() or isInstanceConstructor() }
predicate isConstructor() { this.isStaticConstructor() or this.isInstanceConstructor() }
/** Holds if this method is a destructor/finalizer. */
predicate isFinalizer() { getOverriddenMethod*().getQualifiedName() = "System.Object.Finalize" }
predicate isFinalizer() {
this.getOverriddenMethod*().getQualifiedName() = "System.Object.Finalize"
}
/** Holds if this method is an operator. */
predicate isOperator() { isSpecial() and getName().matches("op\\_%") }
predicate isOperator() { this.isSpecial() and this.getName().matches("op\\_%") }
/** Holds if this method is a getter. */
predicate isGetter() { isSpecial() and getName().matches("get\\_%") }
predicate isGetter() { this.isSpecial() and this.getName().matches("get\\_%") }
/** Holds if this method is a setter. */
predicate isSetter() { isSpecial() and getName().matches("set\\_%") }
predicate isSetter() { this.isSpecial() and this.getName().matches("set\\_%") }
/** Holds if this method is an adder/add event accessor. */
predicate isAdder() { isSpecial() and getName().matches("add\\_%") }
predicate isAdder() { this.isSpecial() and this.getName().matches("add\\_%") }
/** Holds if this method is a remover/remove event accessor. */
predicate isRemove() { isSpecial() and getName().matches("remove\\_%") }
predicate isRemove() { this.isSpecial() and this.getName().matches("remove\\_%") }
/** Holds if this method is an implicit conversion operator. */
predicate isImplicitConversion() { isSpecial() and getName() = "op_Implicit" }
predicate isImplicitConversion() { this.isSpecial() and this.getName() = "op_Implicit" }
/** Holds if this method is an explicit conversion operator. */
predicate isExplicitConversion() { isSpecial() and getName() = "op_Explicit" }
predicate isExplicitConversion() { this.isSpecial() and this.getName() = "op_Explicit" }
/** Holds if this method is a conversion operator. */
predicate isConversion() { isImplicitConversion() or isExplicitConversion() }
predicate isConversion() { this.isImplicitConversion() or this.isExplicitConversion() }
/**
* Gets a method that is overridden, either in a base class
@@ -176,7 +182,7 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN
/** Gets a method that overrides this method, if any. */
final Method getAnOverrider() { result.getOverriddenMethod() = this }
override predicate hasBody() { exists(getImplementation()) }
override predicate hasBody() { exists(this.getImplementation()) }
override predicate canReturn(DotNet::Expr expr) {
exists(Return ret | ret.getImplementation() = this.getImplementation() and expr = ret.getExpr())
@@ -206,7 +212,7 @@ class InstanceConstructor extends Constructor {
/** A method that always returns the `this` parameter. */
class ChainingMethod extends Method {
ChainingMethod() {
forex(Return ret | ret = getImplementation().getAnInstruction() |
forex(Return ret | ret = this.getImplementation().getAnInstruction() |
ret.getExpr() instanceof ThisAccess
)
}
@@ -231,7 +237,7 @@ class Getter extends Accessor {
*/
class TrivialGetter extends Method {
TrivialGetter() {
exists(MethodImplementation impl | impl = getAnImplementation() |
exists(MethodImplementation impl | impl = this.getAnImplementation() |
impl.getInstruction(0) instanceof ThisAccess and
impl.getInstruction(1) instanceof FieldReadAccess and
impl.getInstruction(2) instanceof Return
@@ -239,7 +245,9 @@ class TrivialGetter extends Method {
}
/** Gets the underlying field of this getter. */
Field getField() { getImplementation().getAnInstruction().(FieldReadAccess).getTarget() = result }
Field getField() {
this.getImplementation().getAnInstruction().(FieldReadAccess).getTarget() = result
}
}
/** A setter. */
@@ -262,7 +270,7 @@ class Setter extends Accessor {
*/
class TrivialSetter extends Method {
TrivialSetter() {
exists(MethodImplementation impl | impl = getImplementation() |
exists(MethodImplementation impl | impl = this.getImplementation() |
impl.getInstruction(0) instanceof ThisAccess and
impl.getInstruction(1).(ParameterReadAccess).getTarget().getIndex() = 1 and
impl.getInstruction(2) instanceof FieldWriteAccess
@@ -271,7 +279,7 @@ class TrivialSetter extends Method {
/** Gets the underlying field of this setter. */
Field getField() {
result = getImplementation().getAnInstruction().(FieldWriteAccess).getTarget()
result = this.getImplementation().getAnInstruction().(FieldWriteAccess).getTarget()
}
}
@@ -283,5 +291,5 @@ class Operator extends Method {
Operator() { this.isOperator() }
/** Gets the name of the implementing method (for compatibility with C# data model). */
string getFunctionName() { result = getName() }
string getFunctionName() { result = this.getName() }
}

View File

@@ -19,7 +19,7 @@ class TypeContainer extends DotNet::NamedElement, @cil_type_container {
/** A namespace. */
class Namespace extends DotNet::Namespace, TypeContainer, @namespace {
override string toString() { result = getQualifiedName() }
override string toString() { result = this.getQualifiedName() }
override Namespace getParent() { result = this.getParentNamespace() }
@@ -39,7 +39,7 @@ class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type {
override string toString() { result = this.getName() }
/** Gets the containing type of this type, if any. */
override Type getDeclaringType() { result = getParent() }
override Type getDeclaringType() { result = this.getParent() }
/** Gets a member of this type, if any. */
Member getAMember() { result.getDeclaringType() = this }
@@ -96,13 +96,13 @@ class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type {
Type getABaseInterface() { cil_base_interface(this, result) }
/** Gets an immediate base type of this type, if any. */
Type getABaseType() { result = getBaseClass() or result = getABaseInterface() }
Type getABaseType() { result = this.getBaseClass() or result = this.getABaseInterface() }
/** Gets an immediate subtype of this type, if any. */
Type getASubtype() { result.getABaseType() = this }
/** Gets the namespace directly containing this type, if any. */
Namespace getNamespace() { result = getParent() }
Namespace getNamespace() { result = this.getParent() }
/**
* Gets an index for implicit conversions. A type can be converted to another numeric type

View File

@@ -12,7 +12,7 @@ class TypeParameter extends DotNet::TypeParameter, Type, @cil_typeparameter {
/** Gets the generic type/method declaring this type parameter. */
TypeContainer getGeneric() { cil_type_parameter(result, _, this) }
override Location getLocation() { result = getParent().getLocation() }
override Location getLocation() { result = this.getParent().getLocation() }
/** Holds if this type parameter has the `new` constraint. */
predicate isDefaultConstructible() { cil_typeparam_new(this) }
@@ -34,11 +34,11 @@ class TypeParameter extends DotNet::TypeParameter, Type, @cil_typeparameter {
/** A value or reference type. */
class ValueOrRefType extends DotNet::ValueOrRefType, Type, @cil_valueorreftype {
override ValueOrRefType getDeclaringType() { result = getParent() }
override ValueOrRefType getDeclaringType() { result = this.getParent() }
override string getUndecoratedName() { cil_type(this, result, _, _, _) }
override Namespace getDeclaringNamespace() { result = getNamespace() }
override Namespace getDeclaringNamespace() { result = this.getNamespace() }
override ValueOrRefType getABaseType() { result = Type.super.getABaseType() }
}
@@ -79,7 +79,7 @@ class ArrayType extends DotNet::ArrayType, Type, @cil_array_type {
override string toStringWithTypes() { result = DotNet::ArrayType.super.toStringWithTypes() }
override Location getLocation() { result = getElementType().getLocation() }
override Location getLocation() { result = this.getElementType().getLocation() }
override ValueOrRefType getABaseType() { result = Type.super.getABaseType() }
}
@@ -92,7 +92,7 @@ class PointerType extends DotNet::PointerType, PrimitiveType, @cil_pointer_type
override string getName() { result = DotNet::PointerType.super.getName() }
override Location getLocation() { result = getReferentType().getLocation() }
override Location getLocation() { result = this.getReferentType().getLocation() }
override string toString() { result = DotNet::PointerType.super.toString() }
@@ -312,13 +312,13 @@ class FunctionPointerType extends Type, CustomModifierReceiver, Parameterizable,
override string toString() { result = Type.super.toString() }
/** Holds if the return type is `void`. */
predicate returnsVoid() { getReturnType() instanceof VoidType }
predicate returnsVoid() { this.getReturnType() instanceof VoidType }
/** Gets the number of stack items pushed in a call to this method. */
int getCallPushCount() { if returnsVoid() then result = 0 else result = 1 }
int getCallPushCount() { if this.returnsVoid() then result = 0 else result = 1 }
/** Gets the number of stack items popped in a call to this method. */
int getCallPopCount() { result = count(getRawParameter(_)) }
int getCallPopCount() { result = count(this.getRawParameter(_)) }
override string getLabel() { result = getName() }
override string getLabel() { result = this.getName() }
}

View File

@@ -17,10 +17,10 @@ class Variable extends DotNet::Variable, Declaration, DataFlowNode, @cil_variabl
VariableAccess getAnAccess() { result.getTarget() = this }
/** Gets a read access to this variable, if any. */
ReadAccess getARead() { result = getAnAccess() }
ReadAccess getARead() { result = this.getAnAccess() }
/** Gets a write access to this variable, if any. */
WriteAccess getAWrite() { result = getAnAccess() }
WriteAccess getAWrite() { result = this.getAnAccess() }
override string toString() { result = Declaration.super.toString() }
@@ -40,20 +40,21 @@ class StackVariable extends Variable, @cil_stack_variable {
class LocalVariable extends StackVariable, @cil_local_variable {
override string toString() {
result =
"Local variable " + getIndex() + " of method " + getImplementation().getMethod().getName()
"Local variable " + this.getIndex() + " of method " +
this.getImplementation().getMethod().getName()
}
/** Gets the method implementation defining this local variable. */
MethodImplementation getImplementation() { this = result.getALocalVariable() }
/** Gets the index number of this local variable. This is not usually significant. */
int getIndex() { this = getImplementation().getLocalVariable(result) }
int getIndex() { this = this.getImplementation().getLocalVariable(result) }
override Type getType() { cil_local_variable(this, _, _, result) }
override Location getLocation() { result = getImplementation().getLocation() }
override Location getLocation() { result = this.getImplementation().getLocation() }
override Method getMethod() { result = getImplementation().getMethod() }
override Method getMethod() { result = this.getImplementation().getMethod() }
}
/** A parameter of a `Method` or `FunctionPointerType`. */
@@ -64,7 +65,7 @@ class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_paramete
int getIndex() { cil_parameter(this, _, result, _) }
override string toString() {
result = "Parameter " + getIndex() + " of " + getDeclaringElement().getName()
result = "Parameter " + this.getIndex() + " of " + this.getDeclaringElement().getName()
}
override Type getType() { cil_parameter(this, _, _, result) }
@@ -82,23 +83,25 @@ class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_paramete
predicate hasInFlag() { cil_parameter_in(this) }
/** Holds if this parameter has C# `out` semantics. */
override predicate isOut() { hasOutFlag() and not hasInFlag() }
override predicate isOut() { this.hasOutFlag() and not this.hasInFlag() }
/** Holds if this parameter has C# `ref` semantics. */
override predicate isRef() { hasOutFlag() and hasInFlag() }
override predicate isRef() { this.hasOutFlag() and this.hasInFlag() }
override string toStringWithTypes() { result = getPrefix() + getType().toStringWithTypes() }
override string toStringWithTypes() {
result = this.getPrefix() + this.getType().toStringWithTypes()
}
private string getPrefix() {
if isOut()
if this.isOut()
then result = "out "
else
if isRef()
if this.isRef()
then result = "ref "
else result = ""
}
override Location getLocation() { result = getDeclaringElement().getLocation() }
override Location getLocation() { result = this.getDeclaringElement().getLocation() }
}
/** A method parameter. */
@@ -110,11 +113,11 @@ class MethodParameter extends Parameter, StackVariable {
/** Gets a parameter in an overridden method. */
MethodParameter getOverriddenParameter() {
result = getMethod().getOverriddenMethod().getRawParameter(getRawPosition())
result = this.getMethod().getOverriddenMethod().getRawParameter(this.getRawPosition())
}
override MethodParameter getUnboundDeclaration() {
result = getMethod().getUnboundDeclaration().getRawParameter(getRawPosition())
result = this.getMethod().getUnboundDeclaration().getRawParameter(this.getRawPosition())
}
override string toString() { result = Parameter.super.toString() }
@@ -136,10 +139,10 @@ class ThisParameter extends MethodParameter {
/** A field. */
class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @cil_field {
override string toString() { result = getName() }
override string toString() { result = this.getName() }
override string toStringWithTypes() {
result = getDeclaringType().toStringWithTypes() + "." + getName()
result = this.getDeclaringType().toStringWithTypes() + "." + this.getName()
}
override string getName() { cil_field(this, _, result, _) }
@@ -148,5 +151,5 @@ class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @ci
override ValueOrRefType getDeclaringType() { cil_field(this, result, _, _) }
override Location getLocation() { result = getDeclaringType().getLocation() }
override Location getLocation() { result = this.getDeclaringType().getLocation() }
}

View File

@@ -67,7 +67,7 @@ private module Annotations {
Nullability() { this = TNullability(nullability) }
override string toString() { result = getMemberString() + getSelfNullability() }
override string toString() { result = this.getMemberString() + this.getSelfNullability() }
language[monotonicAggregates]
private string getMemberString() {
@@ -125,7 +125,9 @@ private module Annotations {
}
/** Gets a textual representation of this type annotation. */
string toString() { result = getTypePrefix() + getNullability() + getTypeSuffix() }
string toString() {
result = this.getTypePrefix() + this.getNullability() + this.getTypeSuffix()
}
private int getFlags() { this = TAnnotationFlags(result, _) }
@@ -136,7 +138,7 @@ private module Annotations {
/** Gets an annotation in this set of annotations. */
TypeAnnotation getAnAnnotation() {
isSet(result.getBit())
this.isSet(result.getBit())
or
result = this.getNullability()
}
@@ -298,7 +300,7 @@ class AnnotatedType extends TAnnotatedType {
/** Gets a textual representation of this annotated type. */
string toString() {
result =
annotations.getTypePrefix() + getUnderlyingType().toStringWithTypes() +
annotations.getTypePrefix() + this.getUnderlyingType().toStringWithTypes() +
annotations.getTypeSuffix()
}
@@ -327,7 +329,7 @@ class AnnotatedType extends TAnnotatedType {
/** Gets a type annotation of this annotated type. */
private Annotations::TypeAnnotation getAnAnnotation() {
result = getAnnotations().getAnAnnotation()
result = this.getAnnotations().getAnAnnotation()
}
/** Holds if the type is a non-nullable reference, for example, `string` in a nullable-enabled context. */
@@ -376,7 +378,7 @@ class AnnotatedArrayType extends AnnotatedType {
private string getDimensionString(AnnotatedType elementType) {
exists(AnnotatedType et, string res |
et = getElementType() and
et = this.getElementType() and
res = type.getArraySuffix() and
if et.getUnderlyingType() instanceof ArrayType and not et.isNullableRefType()
then result = res + et.(AnnotatedArrayType).getDimensionString(elementType)

View File

@@ -89,7 +89,7 @@ class Attribute extends TopLevelExprParent, @attribute {
override Location getALocation() { attribute_location(this, result) }
override string toString() {
exists(string type, string name | type = getType().getName() |
exists(string type, string name | type = this.getType().getName() |
(if type.matches("%Attribute") then name = type.prefix(type.length() - 9) else name = type) and
result = "[" + name + "(...)]"
)

View File

@@ -117,7 +117,7 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
final BlockStmt getAStatementBody() { result = this.getStatementBody() }
/** Holds if this callable has a statement body. */
final predicate hasStatementBody() { exists(getStatementBody()) }
final predicate hasStatementBody() { exists(this.getStatementBody()) }
/**
* Gets the expression body of this callable (if any), specified by `=>`.
@@ -157,7 +157,7 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
deprecated final Expr getAnExpressionBody() { result = this.getExpressionBody() }
/** Holds if this callable has an expression body. */
final predicate hasExpressionBody() { exists(getExpressionBody()) }
final predicate hasExpressionBody() { exists(this.getExpressionBody()) }
/** Gets the entry point in the control graph for this callable. */
ControlFlow::Nodes::EntryNode getEntryPoint() { result.getCallable() = this }
@@ -218,7 +218,9 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
exists(YieldReturnStmt yield | yield.getEnclosingCallable() = this | e = yield.getExpr())
}
override string toStringWithTypes() { result = getName() + "(" + parameterTypesToString() + ")" }
override string toStringWithTypes() {
result = this.getName() + "(" + this.parameterTypesToString() + ")"
}
/** Gets a `Call` that has this callable as a target. */
Call getACall() { this = result.getTarget() }
@@ -270,18 +272,18 @@ class Method extends Callable, Virtualizable, Attributable, @method {
override Location getALocation() { method_location(this, result) }
/** Holds if this method is an extension method. */
predicate isExtensionMethod() { getParameter(0).hasExtensionMethodModifier() }
predicate isExtensionMethod() { this.getParameter(0).hasExtensionMethodModifier() }
/** Gets the type of the `params` parameter of this method, if any. */
Type getParamsType() {
exists(Parameter last | last = getParameter(getNumberOfParameters() - 1) |
exists(Parameter last | last = this.getParameter(this.getNumberOfParameters() - 1) |
last.isParams() and
result = last.getType().(ArrayType).getElementType()
)
}
/** Holds if this method has a `params` parameter. */
predicate hasParams() { exists(getParamsType()) }
predicate hasParams() { exists(this.getParamsType()) }
// Remove when `Callable.isOverridden()` is removed
override predicate isOverridden() { Virtualizable.super.isOverridden() }
@@ -316,7 +318,7 @@ class ExtensionMethod extends Method {
/** Gets the type being extended by this method. */
pragma[noinline]
Type getExtendedType() { result = getParameter(0).getType() }
Type getExtendedType() { result = this.getParameter(0).getType() }
override string getAPrimaryQlClass() { result = "ExtensionMethod" }
}
@@ -355,7 +357,7 @@ class Constructor extends DotNet::Constructor, Callable, Member, Attributable, @
ConstructorInitializer getInitializer() { result = this.getChildExpr(-1) }
/** Holds if this constructor has an initializer. */
predicate hasInitializer() { exists(getInitializer()) }
predicate hasInitializer() { exists(this.getInitializer()) }
override ValueOrRefType getDeclaringType() { constructors(this, _, result, _) }
@@ -467,7 +469,7 @@ class Operator extends Callable, Member, Attributable, @operator {
override string toString() { result = Callable.super.toString() }
override Parameter getRawParameter(int i) { result = getParameter(i) }
override Parameter getRawParameter(int i) { result = this.getParameter(i) }
}
/** A clone method on a record. */
@@ -999,10 +1001,10 @@ class LocalFunction extends Callable, Modifiable, Attributable, @local_function
override Type getReturnType() { local_functions(this, _, result, _) }
override Element getParent() { result = getStatement().getParent() }
override Element getParent() { result = this.getStatement().getParent() }
/** Gets the local function statement defining this function. */
LocalFunctionStmt getStatement() { result.getLocalFunction() = getUnboundDeclaration() }
LocalFunctionStmt getStatement() { result.getLocalFunction() = this.getUnboundDeclaration() }
override Callable getEnclosingCallable() { result = this.getStatement().getEnclosingCallable() }
@@ -1011,9 +1013,9 @@ class LocalFunction extends Callable, Modifiable, Attributable, @local_function
name = this.getName()
}
override Location getALocation() { result = getStatement().getALocation() }
override Location getALocation() { result = this.getStatement().getALocation() }
override Parameter getRawParameter(int i) { result = getParameter(i) }
override Parameter getRawParameter(int i) { result = this.getParameter(i) }
override string getAPrimaryQlClass() { result = "LocalFunction" }

View File

@@ -11,7 +11,7 @@ import Location
/**
* A single line of comment.
*
* Either a single line comment (`SingleLineComment`), an XML comment (`XmlComment`),
* Either a single line comment (`SinglelineComment`), an XML comment (`XmlComment`),
* or a line in a multi-line comment (`MultilineComment`).
*/
class CommentLine extends @commentline {

View File

@@ -31,7 +31,7 @@ class Element extends DotNet::Element, @element {
Element getParent() { result.getAChild() = this }
/** Gets a child of this element, if any. */
Element getAChild() { result = getChild(_) }
Element getAChild() { result = this.getChild(_) }
/** Gets the `i`th child of this element (zero-based). */
Element getChild(int i) { none() }

View File

@@ -29,10 +29,10 @@ class Event extends DeclarationWithAccessors, @event {
EventAccessor getAnEventAccessor() { result.getDeclaration() = this }
/** Gets the `add` accessor of this event, if any. */
AddEventAccessor getAddEventAccessor() { result = getAnEventAccessor() }
AddEventAccessor getAddEventAccessor() { result = this.getAnEventAccessor() }
/** Gets the `remove` accessor of this event, if any. */
RemoveEventAccessor getRemoveEventAccessor() { result = getAnEventAccessor() }
RemoveEventAccessor getRemoveEventAccessor() { result = this.getAnEventAccessor() }
/**
* Holds if this event can be used like a field within its declaring type
@@ -111,9 +111,9 @@ class EventAccessor extends Accessor, @event_accessor {
* ```
*/
class AddEventAccessor extends EventAccessor, @add_event_accessor {
override string getName() { result = "add" + "_" + getDeclaration().getName() }
override string getName() { result = "add" + "_" + this.getDeclaration().getName() }
override string getUndecoratedName() { result = "add" + "_" + getDeclaration().getName() }
override string getUndecoratedName() { result = "add" + "_" + this.getDeclaration().getName() }
override string getAPrimaryQlClass() { result = "AddEventAccessor" }
}
@@ -132,9 +132,9 @@ class AddEventAccessor extends EventAccessor, @add_event_accessor {
* ```
*/
class RemoveEventAccessor extends EventAccessor, @remove_event_accessor {
override string getName() { result = "remove" + "_" + getDeclaration().getName() }
override string getName() { result = "remove" + "_" + this.getDeclaration().getName() }
override string getUndecoratedName() { result = "remove" + "_" + getDeclaration().getName() }
override string getUndecoratedName() { result = "remove" + "_" + this.getDeclaration().getName() }
override string getAPrimaryQlClass() { result = "RemoveEventAccessor" }
}

View File

@@ -47,7 +47,7 @@ class Container extends @container {
*/
string getRelativePath() {
exists(string absPath, string pref |
absPath = getAbsolutePath() and sourceLocationPrefix(pref)
absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
|
absPath = pref and result = ""
or
@@ -74,7 +74,7 @@ class Container extends @container {
* </table>
*/
string getBaseName() {
result = getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
}
/**
@@ -100,7 +100,9 @@ class Container extends @container {
* <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
* </table>
*/
string getExtension() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3) }
string getExtension() {
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3)
}
/**
* Gets the stem of this container, that is, the prefix of its base name up to
@@ -119,7 +121,9 @@ class Container extends @container {
* <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
* </table>
*/
string getStem() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1) }
string getStem() {
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1)
}
/** Gets the parent container of this file or folder, if any. */
Container getParentContainer() { containerparent(result, this) }
@@ -128,52 +132,52 @@ class Container extends @container {
Container getAChildContainer() { this = result.getParentContainer() }
/** Gets a file in this container. */
File getAFile() { result = getAChildContainer() }
File getAFile() { result = this.getAChildContainer() }
/** Gets the file in this container that has the given `baseName`, if any. */
File getFile(string baseName) {
result = getAFile() and
result = this.getAFile() and
result.getBaseName() = baseName
}
/** Gets a sub-folder in this container. */
Folder getAFolder() { result = getAChildContainer() }
Folder getAFolder() { result = this.getAChildContainer() }
/** Gets the sub-folder in this container that has the given `baseName`, if any. */
Folder getFolder(string baseName) {
result = getAFolder() and
result = this.getAFolder() and
result.getBaseName() = baseName
}
/** Gets the file or sub-folder in this container that has the given `name`, if any. */
Container getChildContainer(string name) {
result = getAChildContainer() and
result = this.getAChildContainer() and
result.getBaseName() = name
}
/** Gets the file in this container that has the given `stem` and `extension`, if any. */
File getFile(string stem, string extension) {
result = getAChildContainer() and
result = this.getAChildContainer() and
result.getStem() = stem and
result.getExtension() = extension
}
/** Gets a sub-folder contained in this container. */
Folder getASubFolder() { result = getAChildContainer() }
Folder getASubFolder() { result = this.getAChildContainer() }
/**
* Gets a textual representation of the path of this container.
*
* This is the absolute path of the container.
*/
string toString() { result = getAbsolutePath() }
string toString() { result = this.getAbsolutePath() }
}
/** A folder. */
class Folder extends Container, @folder {
override string getAbsolutePath() { folders(this, result) }
override string getURL() { result = "folder://" + getAbsolutePath() }
override string getURL() { result = "folder://" + this.getAbsolutePath() }
}
/** A file. */

View File

@@ -71,14 +71,14 @@ class ConstructedGeneric extends DotNet::ConstructedGeneric, Generic {
override UnboundGeneric getUnboundGeneric() { constructed_generic(this, result) }
override UnboundGeneric getUnboundDeclaration() {
result = getUnboundGeneric().getUnboundDeclaration()
result = this.getUnboundGeneric().getUnboundDeclaration()
}
override int getNumberOfTypeArguments() { result = count(int i | type_arguments(_, i, this)) }
override Type getTypeArgument(int i) { none() }
override Type getATypeArgument() { result = getTypeArgument(_) }
override Type getATypeArgument() { result = this.getTypeArgument(_) }
/** Gets the annotated type of type argument `i`. */
final AnnotatedType getAnnotatedTypeArgument(int i) { result.appliesToTypeArgument(this, i) }
@@ -141,7 +141,7 @@ class UnboundGenericType extends ValueOrRefType, UnboundGeneric {
result = ValueOrRefType.super.getUnboundDeclaration()
}
final override Type getChild(int n) { result = getTypeParameter(n) }
final override Type getChild(int n) { result = this.getTypeParameter(n) }
override string toStringWithTypes() {
result = this.getUndecoratedName() + "<" + getTypeParametersToString(this) + ">"
@@ -173,7 +173,7 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
TypeParameterConstraints getConstraints() { result.getTypeParameter() = this }
override predicate isRefType() {
exists(TypeParameterConstraints tpc | tpc = getConstraints() |
exists(TypeParameterConstraints tpc | tpc = this.getConstraints() |
tpc.hasRefTypeConstraint() or
tpc.getATypeConstraint() instanceof Class or
tpc.getATypeConstraint().(TypeParameter).isRefType()
@@ -182,7 +182,7 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
}
override predicate isValueType() {
exists(TypeParameterConstraints tpc | tpc = getConstraints() |
exists(TypeParameterConstraints tpc | tpc = this.getConstraints() |
tpc.hasValueTypeConstraint() or
tpc.getATypeConstraint().(TypeParameter).isValueType()
)
@@ -219,9 +219,9 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
/** Gets a non-type-parameter type that was transitively supplied for this parameter. */
Type getAnUltimatelySuppliedType() {
result = getASuppliedType() and not result instanceof TypeParameter
result = this.getASuppliedType() and not result instanceof TypeParameter
or
result = getASuppliedType().(TypeParameter).getAnUltimatelySuppliedType()
result = this.getASuppliedType().(TypeParameter).getAnUltimatelySuppliedType()
}
override int getIndex() { type_parameters(this, result, _, _) }
@@ -376,8 +376,8 @@ class UnboundGenericDelegateType extends DelegateType, UnboundGenericType {
override string toStringWithTypes() {
result =
getUndecoratedName() + "<" + getTypeParametersToString(this) + ">(" + parameterTypesToString()
+ ")"
this.getUndecoratedName() + "<" + getTypeParametersToString(this) + ">(" +
this.parameterTypesToString() + ")"
}
}
@@ -404,7 +404,7 @@ class ConstructedType extends ValueOrRefType, ConstructedGeneric {
override UnboundGenericType getUnboundGeneric() { constructed_generic(this, getTypeRef(result)) }
final override Type getChild(int n) { result = getTypeArgument(n) }
final override Type getChild(int n) { result = this.getTypeArgument(n) }
final override string toStringWithTypes() {
result = this.getUndecoratedName() + "<" + getTypeArgumentsToString(this) + ">"
@@ -542,12 +542,12 @@ class UnboundGenericMethod extends Method, UnboundGeneric {
override string toStringWithTypes() {
result =
getUndecoratedName() + "<" + getTypeParametersToString(this) + ">" + "(" +
parameterTypesToString() + ")"
this.getUndecoratedName() + "<" + getTypeParametersToString(this) + ">" + "(" +
this.parameterTypesToString() + ")"
}
final override string getName() {
result = getUndecoratedName() + "<" + getTypeParameterCommas(this) + ">"
result = this.getUndecoratedName() + "<" + getTypeParameterCommas(this) + ">"
}
final override string getUndecoratedName() { methods(this, result, _, _, _) }
@@ -580,8 +580,8 @@ class ConstructedMethod extends Method, ConstructedGeneric {
override string toStringWithTypes() {
result =
getUndecoratedName() + "<" + getTypeArgumentsToString(this) + ">" + "(" +
parameterTypesToString() + ")"
this.getUndecoratedName() + "<" + getTypeArgumentsToString(this) + ">" + "(" +
this.parameterTypesToString() + ")"
}
override UnboundGenericMethod getUnboundDeclaration() {
@@ -589,12 +589,12 @@ class ConstructedMethod extends Method, ConstructedGeneric {
}
final override string getName() {
result = getUndecoratedName() + "<" + getTypeArgumentsNames(this) + ">"
result = this.getUndecoratedName() + "<" + getTypeArgumentsNames(this) + ">"
}
override predicate hasQualifiedName(string qualifier, string name) {
qualifier = getDeclaringType().getQualifiedName() and
name = getUndecoratedName() + "<" + getTypeArgumentsQualifiedNames(this) + ">"
qualifier = this.getDeclaringType().getQualifiedName() and
name = this.getUndecoratedName() + "<" + getTypeArgumentsQualifiedNames(this) + ">"
}
final override string getUndecoratedName() { methods(this, result, _, _, _) }

View File

@@ -155,7 +155,9 @@ class Modifiable extends Declaration, @modifiable {
* Holds if this declaration is effectively `public`, meaning that it can be
* referenced outside the declaring assembly.
*/
predicate isEffectivelyPublic() { not isEffectivelyPrivate() and not isEffectivelyInternal() }
predicate isEffectivelyPublic() {
not this.isEffectivelyPrivate() and not this.isEffectivelyInternal()
}
}
/** A declaration that is a member of a type. */
@@ -193,12 +195,12 @@ class Virtualizable extends Member, @virtualizable {
override predicate isPublic() {
Member.super.isPublic() or
implementsExplicitInterface()
this.implementsExplicitInterface()
}
override predicate isPrivate() {
super.isPrivate() and
not implementsExplicitInterface()
not this.implementsExplicitInterface()
}
/**
@@ -211,17 +213,17 @@ class Virtualizable extends Member, @virtualizable {
/**
* Holds if this member implements an interface member explicitly.
*/
predicate implementsExplicitInterface() { exists(getExplicitlyImplementedInterface()) }
predicate implementsExplicitInterface() { exists(this.getExplicitlyImplementedInterface()) }
/** Holds if this member can be overridden or implemented. */
predicate isOverridableOrImplementable() {
not isSealed() and
not getDeclaringType().isSealed() and
not this.isSealed() and
not this.getDeclaringType().isSealed() and
(
isVirtual() or
isOverride() or
isAbstract() or
getDeclaringType() instanceof Interface
this.isVirtual() or
this.isOverride() or
this.isAbstract() or
this.getDeclaringType() instanceof Interface
)
}
@@ -243,10 +245,10 @@ class Virtualizable extends Member, @virtualizable {
Virtualizable getAnOverrider() { this = result.getOverridee() }
/** Holds if this member is overridden by some other member. */
predicate isOverridden() { exists(getAnOverrider()) }
predicate isOverridden() { exists(this.getAnOverrider()) }
/** Holds if this member overrides another member. */
predicate overrides() { exists(getOverridee()) }
predicate overrides() { exists(this.getOverridee()) }
/**
* Gets the interface member that is immediately implemented by this member, if any.
@@ -274,7 +276,7 @@ class Virtualizable extends Member, @virtualizable {
Virtualizable getImplementee(ValueOrRefType t) { implements(this, result, t) }
/** Gets the interface member that is immediately implemented by this member, if any. */
Virtualizable getImplementee() { result = getImplementee(_) }
Virtualizable getImplementee() { result = this.getImplementee(_) }
/**
* Gets a member that immediately implements this interface member, if any.
@@ -338,8 +340,8 @@ class Virtualizable extends Member, @virtualizable {
|
this = implementation
or
getOverridee+() = implementation and
getDeclaringType().getABaseType+() = implementationType
this.getOverridee+() = implementation and
this.getDeclaringType().getABaseType+() = implementationType
)
}
@@ -355,10 +357,10 @@ class Virtualizable extends Member, @virtualizable {
Virtualizable getAnUltimateImplementor() { this = result.getAnUltimateImplementee() }
/** Holds if this interface member is implemented by some other member. */
predicate isImplemented() { exists(getAnImplementor()) }
predicate isImplemented() { exists(this.getAnImplementor()) }
/** Holds if this member implements (transitively) an interface member. */
predicate implements() { exists(getAnUltimateImplementee()) }
predicate implements() { exists(this.getAnUltimateImplementee()) }
/**
* Holds if this member overrides or implements (reflexively, transitively)
@@ -366,8 +368,8 @@ class Virtualizable extends Member, @virtualizable {
*/
predicate overridesOrImplementsOrEquals(Virtualizable that) {
this = that or
getOverridee+() = that or
getAnUltimateImplementee() = that
this.getOverridee+() = that or
this.getAnUltimateImplementee() = that
}
}
@@ -386,7 +388,7 @@ class Parameterizable extends DotNet::Parameterizable, Declaration, @parameteriz
*/
private string parameterTypeToString(int i) {
exists(Parameter p, string prefix |
p = getParameter(i) and
p = this.getParameter(i) and
result = prefix + p.getType().toStringWithTypes()
|
if p.isOut()
@@ -407,6 +409,7 @@ class Parameterizable extends DotNet::Parameterizable, Declaration, @parameteriz
*/
language[monotonicAggregates]
string parameterTypesToString() {
result = concat(int i | exists(getParameter(i)) | parameterTypeToString(i), ", " order by i)
result =
concat(int i | exists(this.getParameter(i)) | this.parameterTypeToString(i), ", " order by i)
}
}

View File

@@ -20,9 +20,9 @@ class Modifier extends Element, @modifier {
*/
class AccessModifier extends Modifier {
AccessModifier() {
hasName("public") or
hasName("private") or
hasName("internal") or
hasName("protected")
this.hasName("public") or
this.hasName("private") or
this.hasName("internal") or
this.hasName("protected")
}
}

View File

@@ -289,7 +289,7 @@ class IfDirective extends ConditionalDirective, @directive_if {
}
/** Gets a sibling `#elif` or `#else` preprocessor directive. */
BranchDirective getASiblingDirective() { result = getSiblingDirective(_) }
BranchDirective getASiblingDirective() { result = this.getSiblingDirective(_) }
override string toString() { result = "#if ..." }

View File

@@ -171,7 +171,7 @@ class PrintAstNode extends TPrintAstNode {
/**
* Gets a child of this node.
*/
final PrintAstNode getAChild() { result = getChild(_) }
final PrintAstNode getAChild() { result = this.getChild(_) }
/**
* Gets the parent of this node, if any.
@@ -189,7 +189,7 @@ class PrintAstNode extends TPrintAstNode {
*/
string getProperty(string key) {
key = "semmle.label" and
result = toString()
result = this.toString()
}
/**
@@ -198,7 +198,7 @@ class PrintAstNode extends TPrintAstNode {
* this.
*/
string getChildEdgeLabel(int childIndex) {
exists(getChild(childIndex)) and
exists(this.getChild(childIndex)) and
result = childIndex.toString()
}
}

View File

@@ -53,10 +53,10 @@ class DeclarationWithAccessors extends AssignableMember, Virtualizable, Attribut
class DeclarationWithGetSetAccessors extends DeclarationWithAccessors, TopLevelExprParent,
@assignable_with_accessors {
/** Gets the `get` accessor of this declaration, if any. */
Getter getGetter() { result = getAnAccessor() }
Getter getGetter() { result = this.getAnAccessor() }
/** Gets the `set` accessor of this declaration, if any. */
Setter getSetter() { result = getAnAccessor() }
Setter getSetter() { result = this.getAnAccessor() }
override DeclarationWithGetSetAccessors getOverridee() {
result = DeclarationWithAccessors.super.getOverridee()
@@ -182,10 +182,10 @@ class Property extends DotNet::Property, DeclarationWithGetSetAccessors, @proper
or
// For library types, we don't know about assignments in constructors. We instead assume that
// arguments passed to parameters of constructors with suitable names.
getDeclaringType().fromLibrary() and
this.getDeclaringType().fromLibrary() and
exists(Parameter param, Constructor c, string propertyName |
propertyName = getName() and
c = getDeclaringType().getAConstructor() and
propertyName = this.getName() and
c = this.getDeclaringType().getAConstructor() and
param = c.getAParameter() and
// Find a constructor parameter with the same name, but with a lower case initial letter.
param.hasName(propertyName.charAt(0).toLowerCase() + propertyName.suffix(1))
@@ -256,7 +256,7 @@ class Indexer extends DeclarationWithGetSetAccessors, Parameterizable, @indexer
override string getUndecoratedName() { indexers(this, result, _, _, _) }
/** Gets the dimension of this indexer, that is, its number of parameters. */
int getDimension() { result = getNumberOfParameters() }
int getDimension() { result = this.getNumberOfParameters() }
override ValueOrRefType getDeclaringType() { indexers(this, _, result, _, _) }
@@ -304,7 +304,9 @@ class Indexer extends DeclarationWithGetSetAccessors, Parameterizable, @indexer
override Location getALocation() { indexer_location(this, result) }
override string toStringWithTypes() { result = getName() + "[" + parameterTypesToString() + "]" }
override string toStringWithTypes() {
result = this.getName() + "[" + this.parameterTypesToString() + "]"
}
override string getAPrimaryQlClass() { result = "Indexer" }
}
@@ -368,17 +370,17 @@ class Accessor extends Callable, Modifiable, Attributable, @callable_accessor {
* ```
*/
override Modifier getAModifier() {
result = getAnAccessModifier()
result = this.getAnAccessModifier()
or
result = getDeclaration().getAModifier() and
not (result instanceof AccessModifier and exists(getAnAccessModifier()))
result = this.getDeclaration().getAModifier() and
not (result instanceof AccessModifier and exists(this.getAnAccessModifier()))
}
override Accessor getUnboundDeclaration() { accessors(this, _, _, _, result) }
override Location getALocation() { accessor_location(this, result) }
override string toString() { result = getName() }
override string toString() { result = this.getName() }
}
/**
@@ -395,11 +397,11 @@ class Accessor extends Callable, Modifiable, Attributable, @callable_accessor {
* ```
*/
class Getter extends Accessor, @getter {
override string getName() { result = "get" + "_" + getDeclaration().getName() }
override string getName() { result = "get" + "_" + this.getDeclaration().getName() }
override string getUndecoratedName() { result = "get" + "_" + getDeclaration().getName() }
override string getUndecoratedName() { result = "get" + "_" + this.getDeclaration().getName() }
override Type getReturnType() { result = getDeclaration().getType() }
override Type getReturnType() { result = this.getDeclaration().getType() }
/**
* Gets the field used in the trival implementation of this getter, if any.
@@ -417,8 +419,8 @@ class Getter extends Accessor, @getter {
*/
Field trivialGetterField() {
exists(ReturnStmt ret |
getStatementBody().getNumberOfStmts() = 1 and
getStatementBody().getAChild() = ret and
this.getStatementBody().getNumberOfStmts() = 1 and
this.getStatementBody().getAChild() = ret and
ret.getExpr() = result.getAnAccess()
)
}
@@ -444,9 +446,9 @@ class Getter extends Accessor, @getter {
* ```
*/
class Setter extends Accessor, @setter {
override string getName() { result = "set" + "_" + getDeclaration().getName() }
override string getName() { result = "set" + "_" + this.getDeclaration().getName() }
override string getUndecoratedName() { result = "set" + "_" + getDeclaration().getName() }
override string getUndecoratedName() { result = "set" + "_" + this.getDeclaration().getName() }
override Type getReturnType() {
exists(this) and // needed to avoid compiler warning
@@ -469,8 +471,8 @@ class Setter extends Accessor, @setter {
*/
Field trivialSetterField() {
exists(AssignExpr assign |
getStatementBody().getNumberOfStmts() = 1 and
assign.getParent() = getStatementBody().getAChild() and
this.getStatementBody().getNumberOfStmts() = 1 and
assign.getParent() = this.getStatementBody().getAChild() and
assign.getLValue() = result.getAnAccess() and
assign.getRValue() = accessToValue()
)
@@ -521,9 +523,9 @@ private ParameterAccess accessToValue() {
*/
class TrivialProperty extends Property {
TrivialProperty() {
isAutoImplemented()
this.isAutoImplemented()
or
getGetter().trivialGetterField() = getSetter().trivialSetterField()
this.getGetter().trivialGetterField() = this.getSetter().trivialSetterField()
or
exists(CIL::TrivialProperty prop | this.matchesHandle(prop))
}

View File

@@ -65,10 +65,10 @@ class BlockStmt extends Stmt, @block_stmt {
int getNumberOfStmts() { result = count(this.getAStmt()) }
/** Gets the first statement in this block, if any. */
Stmt getFirstStmt() { result = getStmt(0) }
Stmt getFirstStmt() { result = this.getStmt(0) }
/** Gets the last statement in this block, if any. */
Stmt getLastStmt() { result = getStmt(getNumberOfStmts() - 1) }
Stmt getLastStmt() { result = this.getStmt(this.getNumberOfStmts() - 1) }
/** Holds if this block is an empty block with no statements. */
predicate isEmpty() { not exists(this.getAStmt()) }
@@ -79,8 +79,8 @@ class BlockStmt extends Stmt, @block_stmt {
}
override Stmt stripSingletonBlocks() {
if getNumberOfStmts() = 1
then result = getAChildStmt().stripSingletonBlocks()
if this.getNumberOfStmts() = 1
then result = this.getAChildStmt().stripSingletonBlocks()
else result = this
}
@@ -420,7 +420,7 @@ class ForStmt extends LoopStmt, @for_stmt {
* }
* ```
*/
Expr getAnInitializer() { result = getInitializer(_) }
Expr getAnInitializer() { result = this.getInitializer(_) }
/**
* Gets the `n`th initializer expression of this `for` loop
@@ -451,7 +451,7 @@ class ForStmt extends LoopStmt, @for_stmt {
* }
* ```
*/
Expr getAnUpdate() { result = getUpdate(_) }
Expr getAnUpdate() { result = this.getUpdate(_) }
/**
* Gets the `n`th update expression of this `for` loop (starting at index 0).
@@ -519,7 +519,7 @@ class ForeachStmt extends LoopStmt, @foreach_stmt {
* ```
*/
LocalVariableDeclExpr getVariableDeclExpr(int i) {
result = getVariableDeclTuple().getArgument(i)
result = this.getVariableDeclTuple().getArgument(i)
or
i = 0 and result = this.getChild(0)
}
@@ -547,7 +547,7 @@ class ForeachStmt extends LoopStmt, @foreach_stmt {
* }
* ```
*/
LocalVariable getVariable(int i) { result = getVariableDeclExpr(i).getVariable() }
LocalVariable getVariable(int i) { result = this.getVariableDeclExpr(i).getVariable() }
/**
* Gets a local variable of this `foreach` loop.
@@ -560,7 +560,7 @@ class ForeachStmt extends LoopStmt, @foreach_stmt {
* }
* ```
*/
LocalVariable getAVariable() { result = getVariable(_) }
LocalVariable getAVariable() { result = this.getVariable(_) }
/**
* Gets a local variable declaration of this `foreach` loop.
@@ -573,7 +573,7 @@ class ForeachStmt extends LoopStmt, @foreach_stmt {
* }
* ```
*/
LocalVariableDeclExpr getAVariableDeclExpr() { result = getVariableDeclExpr(_) }
LocalVariableDeclExpr getAVariableDeclExpr() { result = this.getVariableDeclExpr(_) }
override Expr getCondition() { none() }
@@ -690,8 +690,8 @@ class GotoLabelStmt extends GotoStmt, @goto_stmt {
/** Gets the target statement that this `goto` statement jumps to. */
LabeledStmt getTarget() {
result.getEnclosingCallable() = getEnclosingCallable() and
result.getLabel() = getLabel()
result.getEnclosingCallable() = this.getEnclosingCallable() and
result.getLabel() = this.getLabel()
}
override string getAPrimaryQlClass() { result = "GotoLabelStmt" }
@@ -717,7 +717,7 @@ class GotoCaseStmt extends GotoStmt, @goto_case_stmt {
/** Gets the constant expression that this `goto case` statement jumps to. */
Expr getExpr() { result = this.getChild(0) }
override string getLabel() { result = getExpr().getValue() }
override string getLabel() { result = this.getExpr().getValue() }
override string toString() { result = "goto case ...;" }
@@ -764,14 +764,14 @@ class ThrowStmt extends JumpStmt, ThrowElement, @throw_stmt {
override ExceptionClass getThrownExceptionType() {
result = ThrowElement.super.getThrownExceptionType()
or
result = getRethrowParent().(CatchClause).getCaughtExceptionType()
result = this.getRethrowParent().(CatchClause).getCaughtExceptionType()
}
private ControlFlowElement getRethrowParent() {
result = this and not exists(getExpr())
result = this and not exists(this.getExpr())
or
exists(ControlFlowElement mid |
mid = getRethrowParent() and
mid = this.getRethrowParent() and
not mid instanceof CatchClause and
result = mid.getParent()
)
@@ -785,7 +785,7 @@ class ThrowStmt extends JumpStmt, ThrowElement, @throw_stmt {
* and may be thrown as an exception.
*/
class ExceptionClass extends Class {
ExceptionClass() { getBaseClass*() instanceof SystemExceptionClass }
ExceptionClass() { this.getBaseClass*() instanceof SystemExceptionClass }
}
/**
@@ -897,13 +897,15 @@ class TryStmt extends Stmt, @try_stmt {
override string getAPrimaryQlClass() { result = "TryStmt" }
/** Gets the `catch` clause that handles an exception of type `ex`, if any. */
CatchClause getAnExceptionHandler(ExceptionClass ex) { result = clauseHandlesException(ex, 0) }
CatchClause getAnExceptionHandler(ExceptionClass ex) {
result = this.clauseHandlesException(ex, 0)
}
/**
* Holds if catch clause `cc` definitely handles exceptions of type `ex`.
*/
predicate definitelyHandles(ExceptionClass ex, CatchClause cc) {
cc = getACatchClause() and
cc = this.getACatchClause() and
not exists(cc.getFilterClause()) and
(
cc.getCaughtExceptionType() = ex.getBaseClass*()
@@ -913,22 +915,22 @@ class TryStmt extends Stmt, @try_stmt {
}
private predicate maybeHandles(ExceptionClass ex, CatchClause cc) {
cc = getACatchClause() and
cc = this.getACatchClause() and
cc.getCaughtExceptionType().getBaseClass*() = ex
}
private CatchClause clauseHandlesException(ExceptionClass ex, int n) {
exists(CatchClause clause | clause = getCatchClause(n) |
if definitelyHandles(ex, clause)
exists(CatchClause clause | clause = this.getCatchClause(n) |
if this.definitelyHandles(ex, clause)
then result = clause
else
if maybeHandles(ex, clause)
if this.maybeHandles(ex, clause)
then
result = clause or
result = clauseHandlesException(ex, n + 1)
result = this.clauseHandlesException(ex, n + 1)
else
// Does not handle
result = clauseHandlesException(ex, n + 1)
result = this.clauseHandlesException(ex, n + 1)
)
}
@@ -939,10 +941,10 @@ class TryStmt extends Stmt, @try_stmt {
* `try` statement.
*/
ControlFlowElement getATriedElement() {
result = getBlock()
result = this.getBlock()
or
exists(ControlFlowElement mid |
mid = getATriedElement() and
mid = this.getATriedElement() and
not mid instanceof TryStmt and
result = getAChild(mid, mid.getEnclosingCallable())
)
@@ -996,10 +998,10 @@ class CatchClause extends Stmt, @catch {
* }
* ```
*/
Expr getFilterClause() { result = getChild(2) }
Expr getFilterClause() { result = this.getChild(2) }
/** Holds if this `catch` clause has a filter. */
predicate hasFilterClause() { exists(getFilterClause()) }
predicate hasFilterClause() { exists(this.getFilterClause()) }
/** Holds if this is the last `catch` clause in the `try` statement that it belongs to. */
predicate isLast() {
@@ -1120,7 +1122,7 @@ class LockStmt extends Stmt, @lock_stmt {
override string toString() { result = "lock (...) {...}" }
/** Gets the variable being locked, if any. */
Variable getLockVariable() { result.getAnAccess() = getExpr() }
Variable getLockVariable() { result.getAnAccess() = this.getExpr() }
/** Gets a statement in the scope of this `lock` statement. */
Stmt getALockedStmt() {
@@ -1128,14 +1130,14 @@ class LockStmt extends Stmt, @lock_stmt {
// delegates and lambdas
result.getParent() = this
or
exists(Stmt mid | mid = getALockedStmt() and result.getParent() = mid)
exists(Stmt mid | mid = this.getALockedStmt() and result.getParent() = mid)
}
/** Holds if this statement is of the form `lock(this) { ... }`. */
predicate isLockThis() { getExpr() instanceof ThisAccess }
predicate isLockThis() { this.getExpr() instanceof ThisAccess }
/** Gets the type `T` if this statement is of the form `lock(typeof(T)) { ... }`. */
Type getLockTypeObject() { result = getExpr().(TypeofExpr).getTypeAccess().getTarget() }
Type getLockTypeObject() { result = this.getExpr().(TypeofExpr).getTypeAccess().getTarget() }
override string getAPrimaryQlClass() { result = "LockStmt" }
}
@@ -1453,7 +1455,7 @@ class LocalFunctionStmt extends Stmt, @local_function_stmt {
/** Gets the local function defined by this statement. */
LocalFunction getLocalFunction() { local_function_stmts(this, result) }
override string toString() { result = getLocalFunction().getName() + "(...)" }
override string toString() { result = this.getLocalFunction().getName() + "(...)" }
override string getAPrimaryQlClass() { result = "LocalFunctionStmt" }
}

View File

@@ -37,7 +37,7 @@ class Type extends DotNet::Type, Member, TypeContainer, @type {
predicate containsTypeParameters() {
this instanceof TypeParameter
or
not this instanceof UnboundGenericType and getAChild().containsTypeParameters()
not this instanceof UnboundGenericType and this.getAChild().containsTypeParameters()
}
/** Holds if this type is a reference type, or a type parameter that is a reference type. */
@@ -133,8 +133,8 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
/** Gets an immediate base type of this type, if any. */
override ValueOrRefType getABaseType() {
result = getBaseClass() or
result = getABaseInterface()
result = this.getBaseClass() or
result = this.getABaseInterface()
}
/** Gets an immediate subtype of this type, if any. */
@@ -200,9 +200,9 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
*/
pragma[inline]
predicate hasCallable(Callable c) {
hasMethod(c)
this.hasMethod(c)
or
hasMember(c.(Accessor).getDeclaration())
this.hasMember(c.(Accessor).getDeclaration())
}
/**
@@ -234,63 +234,63 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
or
hasNonOverriddenMember(this.getBaseClass+(), m)
or
hasOverriddenMember(m)
this.hasOverriddenMember(m)
}
cached
private predicate hasOverriddenMember(Virtualizable v) {
v.isOverridden() and
v = getAMember()
v = this.getAMember()
or
getBaseClass().(ValueOrRefType).hasOverriddenMember(v) and
this.getBaseClass().(ValueOrRefType).hasOverriddenMember(v) and
not v.isPrivate() and
not memberOverrides(v)
not this.memberOverrides(v)
}
// Predicate folding for proper join-order
pragma[noinline]
private predicate memberOverrides(Virtualizable v) {
getAMember().(Virtualizable).getOverridee() = v
this.getAMember().(Virtualizable).getOverridee() = v
}
/** Gets a field (or member constant) with the given name. */
Field getField(string name) { result = getAMember() and result.hasName(name) }
Field getField(string name) { result = this.getAMember() and result.hasName(name) }
/** Gets a field (or member constant) of this type, if any. */
Field getAField() { result = this.getField(_) }
/** Gets a member constant of this type, if any. */
MemberConstant getAConstant() { result = getAMember() }
MemberConstant getAConstant() { result = this.getAMember() }
/** Gets a method of this type, if any. */
Method getAMethod() { result = getAMember() }
Method getAMethod() { result = this.getAMember() }
/** Gets a method of this type with the given name. */
Method getAMethod(string name) { result = getAMember() and result.hasName(name) }
Method getAMethod(string name) { result = this.getAMember() and result.hasName(name) }
/** Gets a property of this type, if any. */
Property getAProperty() { result = getAMember() }
Property getAProperty() { result = this.getAMember() }
/** Gets a named property of this type. */
Property getProperty(string name) { result = getAMember() and result.hasName(name) }
Property getProperty(string name) { result = this.getAMember() and result.hasName(name) }
/** Gets an indexer of this type, if any. */
Indexer getAnIndexer() { result = getAMember() }
Indexer getAnIndexer() { result = this.getAMember() }
/** Gets an event of this type, if any. */
Event getAnEvent() { result = getAMember() }
Event getAnEvent() { result = this.getAMember() }
/** Gets a user-defined operator of this type, if any. */
Operator getAnOperator() { result = getAMember() }
Operator getAnOperator() { result = this.getAMember() }
/** Gets a static or instance constructor of this type, if any. */
Constructor getAConstructor() { result = getAMember() }
Constructor getAConstructor() { result = this.getAMember() }
/** Gets the static constructor of this type, if any. */
StaticConstructor getStaticConstructor() { result = getAMember() }
StaticConstructor getStaticConstructor() { result = this.getAMember() }
/** Gets a nested type of this type, if any. */
NestedType getANestedType() { result = getAMember() }
NestedType getANestedType() { result = this.getAMember() }
/** Gets the number of types that directly depend on this type. */
int getAfferentCoupling() { afferentCoupling(this, result) }
@@ -675,10 +675,10 @@ class Enum extends ValueType, @enum_type {
*/
class Struct extends ValueType, @struct_type {
/** Holds if this `struct` has a `ref` modifier. */
predicate isRef() { hasModifier("ref") }
predicate isRef() { this.hasModifier("ref") }
/** Holds if this `struct` has a `readonly` modifier. */
predicate isReadonly() { hasModifier("readonly") }
predicate isReadonly() { this.hasModifier("readonly") }
override string getAPrimaryQlClass() { result = "Struct" }
}
@@ -695,7 +695,7 @@ class RefType extends ValueOrRefType, @ref_type {
/** Gets a member that overrides a non-abstract member in a super type, if any. */
private Virtualizable getAnOverrider() {
getAMember() = result and
this.getAMember() = result and
exists(Virtualizable v | result.getOverridee() = v and not v.isAbstract())
}
@@ -897,14 +897,14 @@ class FunctionPointerType extends Type, Parameterizable, @function_pointer_type
}
/** Gets an unmanaged calling convention. */
Type getAnUnmanagedCallingConvention() { result = getUnmanagedCallingConvention(_) }
Type getAnUnmanagedCallingConvention() { result = this.getUnmanagedCallingConvention(_) }
/** Gets the annotated return type of this function pointer type. */
AnnotatedType getAnnotatedReturnType() { result.appliesTo(this) }
override string getAPrimaryQlClass() { result = "FunctionPointerType" }
override string getLabel() { result = getName() }
override string getLabel() { result = this.getName() }
}
/**
@@ -922,13 +922,15 @@ class NullableType extends ValueType, DotNet::ConstructedGeneric, @nullable_type
*/
Type getUnderlyingType() { nullable_underlying_type(this, getTypeRef(result)) }
override string toStringWithTypes() { result = getUnderlyingType().toStringWithTypes() + "?" }
override string toStringWithTypes() {
result = this.getUnderlyingType().toStringWithTypes() + "?"
}
override Type getChild(int n) { result = getUnderlyingType() and n = 0 }
override Type getChild(int n) { result = this.getUnderlyingType() and n = 0 }
override Location getALocation() { result = getUnderlyingType().getALocation() }
override Location getALocation() { result = this.getUnderlyingType().getALocation() }
override Type getTypeArgument(int p) { p = 0 and result = getUnderlyingType() }
override Type getTypeArgument(int p) { p = 0 and result = this.getUnderlyingType() }
override string getAPrimaryQlClass() { result = "NullableType" }
@@ -966,8 +968,8 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
/** Holds if this array type has the same shape (dimension and rank) as `that` array type. */
predicate hasSameShapeAs(ArrayType that) {
getDimension() = that.getDimension() and
getRank() = that.getRank()
this.getDimension() = that.getDimension() and
this.getRank() = that.getRank()
}
/**
@@ -981,7 +983,7 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
private string getDimensionString(Type elementType) {
exists(Type et, string res |
et = this.getElementType() and
res = getArraySuffix() and
res = this.getArraySuffix() and
if et instanceof ArrayType
then result = res + et.(ArrayType).getDimensionString(elementType)
else (
@@ -996,7 +998,7 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
)
}
override Type getChild(int n) { result = getElementType() and n = 0 }
override Type getChild(int n) { result = this.getElementType() and n = 0 }
override Location getALocation() {
type_location(this, result)
@@ -1021,13 +1023,15 @@ class PointerType extends DotNet::PointerType, Type, @pointer_type {
override string toStringWithTypes() { result = DotNet::PointerType.super.toStringWithTypes() }
override Type getChild(int n) { result = getReferentType() and n = 0 }
override Type getChild(int n) { result = this.getReferentType() and n = 0 }
final override string getName() { types(this, _, result) }
final override string getUndecoratedName() { result = getReferentType().getUndecoratedName() }
final override string getUndecoratedName() {
result = this.getReferentType().getUndecoratedName()
}
override Location getALocation() { result = getReferentType().getALocation() }
override Location getALocation() { result = this.getReferentType().getALocation() }
override string toString() { result = DotNet::PointerType.super.toString() }
@@ -1082,10 +1086,10 @@ class TupleType extends ValueType, @tuple_type {
* Gets the type of the `n`th element of this tuple, indexed from 0.
* For example, the 0th (first) element type of `(int, string)` is `int`.
*/
Type getElementType(int n) { result = getElement(n).getType() }
Type getElementType(int n) { result = this.getElement(n).getType() }
/** Gets an element of this tuple. */
Field getAnElement() { result = getElement(_) }
Field getAnElement() { result = this.getElement(_) }
override Location getALocation() { type_location(this, result) }
@@ -1093,23 +1097,27 @@ class TupleType extends ValueType, @tuple_type {
* Gets the arity of this tuple. For example, the arity of
* `(int, int, double)` is 3.
*/
int getArity() { result = count(getAnElement()) }
int getArity() { result = count(this.getAnElement()) }
language[monotonicAggregates]
override string toStringWithTypes() {
result =
"(" +
concat(Type t, int i | t = getElement(i).getType() | t.toStringWithTypes(), ", " order by i)
+ ")"
concat(Type t, int i |
t = this.getElement(i).getType()
|
t.toStringWithTypes(), ", " order by i
) + ")"
}
language[monotonicAggregates]
override string getName() {
result =
"(" + concat(Type t, int i | t = getElement(i).getType() | t.getName(), "," order by i) + ")"
"(" + concat(Type t, int i | t = this.getElement(i).getType() | t.getName(), "," order by i) +
")"
}
override string getLabel() { result = getUnderlyingType().getLabel() }
override string getLabel() { result = this.getUnderlyingType().getLabel() }
override Type getChild(int i) { result = this.getUnderlyingType().getChild(i) }

View File

@@ -297,7 +297,7 @@ module Gvn {
or
result =
strictconcat(int i, int j |
toStringPart(i, j)
this.toStringPart(i, j)
|
this.toStringConstructedPart(i, j) order by i desc, j
)

View File

@@ -149,7 +149,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
predicate isIn() { params(this, _, _, _, 5, _, _) }
/** Holds if this parameter is an output or reference parameter. */
predicate isOutOrRef() { isOut() or isRef() }
predicate isOutOrRef() { this.isOut() or this.isRef() }
/**
* Holds if this parameter is a parameter array. For example, `args`
@@ -210,7 +210,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
Expr getDefaultValue() { result = this.getUnboundDeclaration().getChildExpr(0) }
/** Holds if this parameter has a default value. */
predicate hasDefaultValue() { exists(getDefaultValue()) }
predicate hasDefaultValue() { exists(this.getDefaultValue()) }
/** Gets the callable to which this parameter belongs, if any. */
override Callable getCallable() { result = this.getDeclaringElement() }
@@ -238,7 +238,9 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
* `y` is `5`, and the assigned arguments to `z` are `3` and `6`, respectively.
*/
pragma[nomagic]
Expr getAnAssignedArgument() { result = getCallable().getACall().getArgumentForParameter(this) }
Expr getAnAssignedArgument() {
result = this.getCallable().getACall().getArgumentForParameter(this)
}
/** Holds if this parameter is potentially overwritten in the body of its callable. */
predicate isOverwritten() {
@@ -323,7 +325,7 @@ class LocalVariable extends LocalScopeVariable, @local_variable {
/** Gets the enclosing callable of this local variable. */
Callable getEnclosingCallable() { result = this.getVariableDeclExpr().getEnclosingCallable() }
override Callable getCallable() { result = getEnclosingCallable() }
override Callable getCallable() { result = this.getEnclosingCallable() }
override predicate isRef() { localvars(this, 3, _, _, _, _) }

View File

@@ -108,7 +108,7 @@ class XMLParent extends @xmlparent {
}
/** Gets the text value contained in this XML parent. */
string getTextValue() { result = allCharactersString() }
string getTextValue() { result = this.allCharactersString() }
/** Gets a printable representation of this XML parent. */
string toString() { result = this.getName() }
@@ -119,7 +119,7 @@ class XMLFile extends XMLParent, File {
XMLFile() { xmlEncoding(this, _) }
/** Gets a printable representation of this XML file. */
override string toString() { result = getName() }
override string toString() { result = this.getName() }
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
@@ -129,14 +129,14 @@ class XMLFile extends XMLParent, File {
*
* Gets the path of this XML file.
*/
deprecated string getPath() { result = getAbsolutePath() }
deprecated string getPath() { result = this.getAbsolutePath() }
/**
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
*
* Gets the path of the folder that contains this XML file.
*/
deprecated string getFolder() { result = getParentContainer().getAbsolutePath() }
deprecated string getFolder() { result = this.getParentContainer().getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }
@@ -200,7 +200,7 @@ class XMLDTD extends XMLLocatable, @xmldtd {
*/
class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
/** Holds if this XML element has the given `name`. */
predicate hasName(string name) { name = getName() }
predicate hasName(string name) { name = this.getName() }
/** Gets the name of this XML element. */
override string getName() { xmlElements(this, result, _, _, _) }
@@ -239,7 +239,7 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }
/** Gets a printable representation of this XML element. */
override string toString() { result = getName() }
override string toString() { result = this.getName() }
}
/**

View File

@@ -42,7 +42,7 @@ abstract class AssertMethod extends Method {
*
* Gets the index of a parameter being asserted.
*/
deprecated final int getAssertionIndex() { result = getAnAssertionIndex() }
deprecated final int getAssertionIndex() { result = this.getAnAssertionIndex() }
/** Gets the parameter at position `i` being asserted. */
final Parameter getAssertedParameter(int i) {
@@ -55,7 +55,7 @@ abstract class AssertMethod extends Method {
*
* Gets a parameter being asserted.
*/
deprecated final Parameter getAssertedParameter() { result = getAssertedParameter(_) }
deprecated final Parameter getAssertedParameter() { result = this.getAssertedParameter(_) }
/** Gets the failure type if the assertion fails for argument `i`, if any. */
abstract AssertionFailure getAssertionFailure(int i);

View File

@@ -57,7 +57,7 @@ abstract class GeneratedCodeComment extends CommentLine { }
*/
class GenericGeneratedCodeComment extends GeneratedCodeComment {
GenericGeneratedCodeComment() {
exists(string line, string entity, string was, string automatically | line = getText() |
exists(string line, string entity, string was, string automatically | line = this.getText() |
entity = "file|class|interface|art[ei]fact|module|script" and
was = "was|is|has been" and
automatically = "automatically |mechanically |auto[- ]?" and
@@ -70,7 +70,7 @@ class GenericGeneratedCodeComment extends GeneratedCodeComment {
/** A comment warning against modifications. */
class DontModifyMarkerComment extends GeneratedCodeComment {
DontModifyMarkerComment() {
exists(string line | line = getText() |
exists(string line | line = this.getText() |
line.regexpMatch("(?i).*\\bGenerated by\\b.*\\bDo not edit\\b.*") or
line.regexpMatch("(?i).*\\bAny modifications to this file will be lost\\b.*")
)

View File

@@ -11,7 +11,7 @@ private import ControlFlow::SuccessorTypes
*/
class BasicBlock extends TBasicBlockStart {
/** Gets an immediate successor of this basic block, if any. */
BasicBlock getASuccessor() { result.getFirstNode() = getLastNode().getASuccessor() }
BasicBlock getASuccessor() { result.getFirstNode() = this.getLastNode().getASuccessor() }
/** Gets an immediate successor of this basic block of a given type, if any. */
BasicBlock getASuccessorByType(ControlFlow::SuccessorType t) {
@@ -42,7 +42,7 @@ class BasicBlock extends TBasicBlockStart {
* The basic block on line 2 is an immediate `true` successor of the
* basic block on line 1.
*/
BasicBlock getATrueSuccessor() { result.getFirstNode() = getLastNode().getATrueSuccessor() }
BasicBlock getATrueSuccessor() { result.getFirstNode() = this.getLastNode().getATrueSuccessor() }
/**
* Gets an immediate `false` successor, if any.
@@ -60,25 +60,27 @@ class BasicBlock extends TBasicBlockStart {
* The basic block on line 2 is an immediate `false` successor of the
* basic block on line 1.
*/
BasicBlock getAFalseSuccessor() { result.getFirstNode() = getLastNode().getAFalseSuccessor() }
BasicBlock getAFalseSuccessor() {
result.getFirstNode() = this.getLastNode().getAFalseSuccessor()
}
/** Gets the control flow node at a specific (zero-indexed) position in this basic block. */
ControlFlow::Node getNode(int pos) { bbIndex(getFirstNode(), result, pos) }
ControlFlow::Node getNode(int pos) { bbIndex(this.getFirstNode(), result, pos) }
/** Gets a control flow node in this basic block. */
ControlFlow::Node getANode() { result = getNode(_) }
ControlFlow::Node getANode() { result = this.getNode(_) }
/** Gets the first control flow node in this basic block. */
ControlFlow::Node getFirstNode() { this = TBasicBlockStart(result) }
/** Gets the last control flow node in this basic block. */
ControlFlow::Node getLastNode() { result = getNode(length() - 1) }
ControlFlow::Node getLastNode() { result = this.getNode(this.length() - 1) }
/** Gets the callable that this basic block belongs to. */
final Callable getCallable() { result = this.getFirstNode().getEnclosingCallable() }
/** Gets the length of this basic block. */
int length() { result = strictcount(getANode()) }
int length() { result = strictcount(this.getANode()) }
/**
* Holds if this basic block immediately dominates basic block `bb`.
@@ -151,7 +153,7 @@ class BasicBlock extends TBasicBlockStart {
*/
predicate dominates(BasicBlock bb) {
bb = this or
strictlyDominates(bb)
this.strictlyDominates(bb)
}
/**
@@ -177,14 +179,14 @@ class BasicBlock extends TBasicBlockStart {
* does not dominate the basic block on line 6.
*/
predicate inDominanceFrontier(BasicBlock df) {
dominatesPredecessor(df) and
not strictlyDominates(df)
this.dominatesPredecessor(df) and
not this.strictlyDominates(df)
}
/**
* Holds if this basic block dominates a predecessor of `df`.
*/
private predicate dominatesPredecessor(BasicBlock df) { dominates(df.getAPredecessor()) }
private predicate dominatesPredecessor(BasicBlock df) { this.dominates(df.getAPredecessor()) }
/**
* Gets the basic block that immediately dominates this basic block, if any.
@@ -263,7 +265,7 @@ class BasicBlock extends TBasicBlockStart {
* post-dominates itself.
*/
predicate postDominates(BasicBlock bb) {
strictlyPostDominates(bb) or
this.strictlyPostDominates(bb) or
this = bb
}
@@ -276,10 +278,10 @@ class BasicBlock extends TBasicBlockStart {
predicate inLoop() { this.getASuccessor+() = this }
/** Gets a textual representation of this basic block. */
string toString() { result = getFirstNode().toString() }
string toString() { result = this.getFirstNode().toString() }
/** Gets the location of this basic block. */
Location getLocation() { result = getFirstNode().getLocation() }
Location getLocation() { result = this.getFirstNode().getLocation() }
}
/**
@@ -420,7 +422,7 @@ private module JoinBlockPredecessors {
/** A basic block with more than one predecessor. */
class JoinBlock extends BasicBlock {
JoinBlock() { getFirstNode().isJoin() }
JoinBlock() { this.getFirstNode().isJoin() }
/**
* Gets the `i`th predecessor of this join block, with respect to some

View File

@@ -72,13 +72,14 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
ControlFlowElement getAReachableElement() {
// Reachable in same basic block
exists(BasicBlock bb, int i, int j |
bb.getNode(i) = getAControlFlowNode() and
bb.getNode(i) = this.getAControlFlowNode() and
bb.getNode(j) = result.getAControlFlowNode() and
i < j
)
or
// Reachable in different basic blocks
getAControlFlowNode().getBasicBlock().getASuccessor+().getANode() = result.getAControlFlowNode()
this.getAControlFlowNode().getBasicBlock().getASuccessor+().getANode() =
result.getAControlFlowNode()
}
pragma[noinline]

View File

@@ -33,10 +33,10 @@ module ControlFlow {
ControlFlowElement getElement() { none() }
/** Gets the location of this control flow node. */
Location getLocation() { result = getElement().getLocation() }
Location getLocation() { result = this.getElement().getLocation() }
/** Holds if this control flow node has conditional successors. */
predicate isCondition() { exists(getASuccessorByType(any(ConditionalSuccessor e))) }
predicate isCondition() { exists(this.getASuccessorByType(any(ConditionalSuccessor e))) }
/** Gets the basic block that this control flow node belongs to. */
BasicBlock getBasicBlock() { result.getANode() = this }
@@ -67,7 +67,7 @@ module ControlFlow {
// potentially very large predicate, so must be inlined
pragma[inline]
predicate dominates(Node that) {
strictlyDominates(that)
this.strictlyDominates(that)
or
this = that
}
@@ -138,7 +138,7 @@ module ControlFlow {
// potentially very large predicate, so must be inlined
pragma[inline]
predicate postDominates(Node that) {
strictlyPostDominates(that)
this.strictlyPostDominates(that)
or
this = that
}
@@ -186,13 +186,13 @@ module ControlFlow {
Node getASuccessorByType(SuccessorType t) { result = getASuccessor(this, t) }
/** Gets an immediate successor, if any. */
Node getASuccessor() { result = getASuccessorByType(_) }
Node getASuccessor() { result = this.getASuccessorByType(_) }
/** Gets an immediate predecessor node of a given flow type, if any. */
Node getAPredecessorByType(SuccessorType t) { result.getASuccessorByType(t) = this }
/** Gets an immediate predecessor, if any. */
Node getAPredecessor() { result = getAPredecessorByType(_) }
Node getAPredecessor() { result = this.getAPredecessorByType(_) }
/**
* Gets an immediate `true` successor, if any.
@@ -211,7 +211,7 @@ module ControlFlow {
* on line 1.
*/
Node getATrueSuccessor() {
result = getASuccessorByType(any(BooleanSuccessor t | t.getValue() = true))
result = this.getASuccessorByType(any(BooleanSuccessor t | t.getValue() = true))
}
/**
@@ -231,7 +231,7 @@ module ControlFlow {
* on line 1.
*/
Node getAFalseSuccessor() {
result = getASuccessorByType(any(BooleanSuccessor t | t.getValue() = false))
result = this.getASuccessorByType(any(BooleanSuccessor t | t.getValue() = false))
}
/** Holds if this node has more than one predecessor. */
@@ -285,7 +285,7 @@ module ControlFlow {
override Callable getEnclosingCallable() { result = this.getCallable() }
override Location getLocation() { result = getCallable().getLocation() }
override Location getLocation() { result = this.getCallable().getLocation() }
override string toString() {
exists(string s |
@@ -293,7 +293,7 @@ module ControlFlow {
or
normal = false and s = "abnormal"
|
result = "exit " + getCallable() + " (" + s + ")"
result = "exit " + this.getCallable() + " (" + s + ")"
)
}
}
@@ -307,9 +307,9 @@ module ControlFlow {
override Callable getEnclosingCallable() { result = this.getCallable() }
override Location getLocation() { result = getCallable().getLocation() }
override Location getLocation() { result = this.getCallable().getLocation() }
override string toString() { result = "exit " + getCallable().toString() }
override string toString() { result = "exit " + this.getCallable().toString() }
}
/**

View File

@@ -1740,7 +1740,7 @@ module Internal {
e = this.getAChildExpr()
or
exists(Expr mid |
descendant(mid) and
this.descendant(mid) and
not interestingDescendantCandidate(mid) and
e = mid.getAChildExpr()
)
@@ -1748,7 +1748,7 @@ module Internal {
/** Holds if `e` is an interesting descendant of this descendant. */
predicate interestingDescendant(Expr e) {
descendant(e) and
this.descendant(e) and
interestingDescendantCandidate(e)
}
}
@@ -1797,7 +1797,7 @@ module Internal {
override predicate candidate(ControlFlowElement x, ControlFlowElement y) {
exists(BasicBlock bb, Declaration d |
candidateAux(x, d, bb) and
this.candidateAux(x, d, bb) and
y =
any(AccessOrCallExpr e |
e.getAControlFlowNode().getBasicBlock() = bb and

View File

@@ -495,7 +495,7 @@ module Expressions {
// Flow from last element of left operand to first element of right operand
last(this.getLeftOperand(), pred, c) and
c.(NullnessCompletion).isNull() and
first(getRightOperand(), succ)
first(this.getRightOperand(), succ)
or
// Post-order: flow from last element of left operand to element itself
last(this.getLeftOperand(), pred, c) and
@@ -504,7 +504,7 @@ module Expressions {
not c.(NullnessCompletion).isNull()
or
// Post-order: flow from last element of right operand to element itself
last(getRightOperand(), pred, c) and
last(this.getRightOperand(), pred, c) and
c instanceof NormalCompletion and
succ = this
}
@@ -575,7 +575,7 @@ module Expressions {
PostOrderTree.super.last(last, c)
or
// Qualifier exits with a `null` completion
lastQualifier(last, c) and
this.lastQualifier(last, c) and
c.(NullnessCompletion).isNull()
}
@@ -1483,7 +1483,7 @@ module Statements {
)
or
// Flow into `finally` block
pred = getAFinallyPredecessor(c, true) and
pred = this.getAFinallyPredecessor(c, true) and
first(this.getFinally(), succ)
}
}

View File

@@ -69,9 +69,9 @@ class PreBasicBlock extends ControlFlowElement {
ControlFlowElement getFirstElement() { result = this }
ControlFlowElement getLastElement() { result = this.getElement(length() - 1) }
ControlFlowElement getLastElement() { result = this.getElement(this.length() - 1) }
int length() { result = strictcount(getAnElement()) }
int length() { result = strictcount(this.getAnElement()) }
predicate immediatelyDominates(PreBasicBlock bb) { bbIDominates(this, bb) }
@@ -117,7 +117,7 @@ class ConditionBlock extends PreBasicBlock {
pragma[nomagic]
predicate controls(PreBasicBlock controlled, SuccessorTypes::ConditionalSuccessor s) {
exists(PreBasicBlock succ, ConditionalCompletion c | immediatelyControls(succ, c) |
exists(PreBasicBlock succ, ConditionalCompletion c | this.immediatelyControls(succ, c) |
succ.dominates(controlled) and
s = c.getAMatchingSuccessorType()
)

View File

@@ -628,7 +628,7 @@ module FinallySplitting {
*/
private predicate exit(ControlFlowElement pred, Completion c, boolean inherited) {
exists(TryStmt try, FinallySplitType type |
exit0(pred, try, this.getNestLevel(), c) and
this.exit0(pred, try, this.getNestLevel(), c) and
type = this.getType()
|
if last(try.getFinally(), pred, c)
@@ -690,18 +690,18 @@ module FinallySplitting {
override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
succ(pred, succ, c) and
(
exit(pred, c, _)
this.exit(pred, c, _)
or
exit(pred, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion(), _)
this.exit(pred, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion(), _)
)
}
override predicate hasExitScope(CfgScope scope, ControlFlowElement last, Completion c) {
scopeLast(scope, last, c) and
(
exit(last, c, _)
this.exit(last, c, _)
or
exit(last, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion(), _)
this.exit(last, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion(), _)
)
}

View File

@@ -77,7 +77,7 @@ module SuccessorTypes {
class BooleanSuccessor extends ConditionalSuccessor, TBooleanSuccessor {
override boolean getValue() { this = TBooleanSuccessor(result) }
override string toString() { result = getValue().toString() }
override string toString() { result = this.getValue().toString() }
}
/**
@@ -310,7 +310,7 @@ module SuccessorTypes {
/** Gets the type of exception. */
ExceptionClass getExceptionClass() { this = TExceptionSuccessor(result) }
override string toString() { result = "exception(" + getExceptionClass().getName() + ")" }
override string toString() { result = "exception(" + this.getExceptionClass().getName() + ")" }
}
/**

View File

@@ -404,6 +404,7 @@ private string paramsString(InterpretedCallable c) {
)
}
pragma[nomagic]
private Element interpretElement0(
string namespace, string type, boolean subtypes, string name, string signature
) {

View File

@@ -505,20 +505,20 @@ class SystemBooleanFlow extends LibraryTypeDataFlow, SystemBooleanStruct {
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
methodFlow(source, sink, c) and
this.methodFlow(source, sink, c) and
preservesValue = false
}
private predicate methodFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationMethod m
) {
m = getParseMethod() and
m = this.getParseMethod() and
(
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
)
or
m = getTryParseMethod() and
m = this.getTryParseMethod() and
(
source = TCallableFlowSourceArg(0) and
(
@@ -537,12 +537,12 @@ class SystemUriFlow extends LibraryTypeDataFlow, SystemUriClass {
boolean preservesValue
) {
(
constructorFlow(source, sink, c)
this.constructorFlow(source, sink, c)
or
methodFlow(source, sink, c)
this.methodFlow(source, sink, c)
or
exists(Property p |
propertyFlow(p) and
this.propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
@@ -552,7 +552,7 @@ class SystemUriFlow extends LibraryTypeDataFlow, SystemUriClass {
}
private predicate constructorFlow(CallableFlowSource source, CallableFlowSink sink, Constructor c) {
c = getAMember() and
c = this.getAMember() and
c.getParameter(0).getType() instanceof StringType and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
@@ -567,11 +567,11 @@ class SystemUriFlow extends LibraryTypeDataFlow, SystemUriClass {
}
private predicate propertyFlow(Property p) {
p = getPathAndQueryProperty()
p = this.getPathAndQueryProperty()
or
p = getQueryProperty()
p = this.getQueryProperty()
or
p = getOriginalStringProperty()
p = this.getOriginalStringProperty()
}
}
@@ -582,15 +582,15 @@ class SystemIOStringReaderFlow extends LibraryTypeDataFlow, SystemIOStringReader
boolean preservesValue
) {
(
constructorFlow(source, sink, c)
this.constructorFlow(source, sink, c)
or
methodFlow(source, sink, c)
this.methodFlow(source, sink, c)
) and
preservesValue = false
}
private predicate constructorFlow(CallableFlowSource source, CallableFlowSink sink, Constructor c) {
c = getAMember() and
c = this.getAMember() and
c.getParameter(0).getType() instanceof StringType and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
@@ -599,7 +599,7 @@ class SystemIOStringReaderFlow extends LibraryTypeDataFlow, SystemIOStringReader
private predicate methodFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationMethod m
) {
m.getDeclaringType() = getABaseType*() and
m.getDeclaringType() = this.getABaseType*() and
m.getName().matches("Read%") and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn()
@@ -612,17 +612,17 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
constructorFlow(source, sourceAp, sink, sinkAp, c) and
this.constructorFlow(source, sourceAp, sink, sinkAp, c) and
preservesValue = false
or
methodFlow(source, sourceAp, sink, sinkAp, c, preservesValue)
this.methodFlow(source, sourceAp, sink, sinkAp, c, preservesValue)
}
private predicate constructorFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
Constructor c
) {
c = getAMember() and
c = this.getAMember() and
c.getParameter(0).getType().(ArrayType).getElementType() instanceof CharType and
source = TCallableFlowSourceArg(0) and
sourceAp = AccessPath::element() and
@@ -641,14 +641,14 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
sinkAp = AccessPath::empty() and
preservesValue = true
or
m = getSplitMethod() and
m = this.getSplitMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::element() and
preservesValue = false
or
m = getReplaceMethod() and
m = this.getReplaceMethod() and
sourceAp = AccessPath::empty() and
sinkAp = AccessPath::empty() and
(
@@ -661,21 +661,21 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
preservesValue = false
)
or
m = getSubstringMethod() and
m = this.getSubstringMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = false
or
m = getCloneMethod() and
m = this.getCloneMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = true
or
m = getInsertMethod() and
m = this.getInsertMethod() and
sourceAp = AccessPath::empty() and
sinkAp = AccessPath::empty() and
(
@@ -688,21 +688,21 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
preservesValue = false
)
or
m = getNormalizeMethod() and
m = this.getNormalizeMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = false
or
m = getRemoveMethod() and
m = this.getRemoveMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = false
or
m = getAMethod() and
m = this.getAMethod() and
m.getName().regexpMatch("((ToLower|ToUpper)(Invariant)?)|(Trim(Start|End)?)|(Pad(Left|Right))") and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
@@ -710,7 +710,7 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
sinkAp = AccessPath::empty() and
preservesValue = false
or
m = getConcatMethod() and
m = this.getConcatMethod() and
exists(int i |
source = getFlowSourceArg(m, i, sourceAp) and
sink = TCallableFlowSinkReturn() and
@@ -718,20 +718,20 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
preservesValue = false
)
or
m = getCopyMethod() and
m = this.getCopyMethod() and
source = TCallableFlowSourceArg(0) and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = true
or
m = getJoinMethod() and
m = this.getJoinMethod() and
source = getFlowSourceArg(m, [0, 1], sourceAp) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = false
or
m = getFormatMethod() and
m = this.getFormatMethod() and
exists(int i |
(m.getParameter(0).getType() instanceof SystemIFormatProviderInterface implies i != 0) and
source = getFlowSourceArg(m, i, sourceAp) and
@@ -749,10 +749,10 @@ class SystemTextStringBuilderFlow extends LibraryTypeDataFlow, SystemTextStringB
SourceDeclarationCallable c, boolean preservesValue
) {
(
constructorFlow(source, sourceAp, sink, sinkAp, c) and
this.constructorFlow(source, sourceAp, sink, sinkAp, c) and
preservesValue = true
or
methodFlow(source, sourceAp, sink, sinkAp, c, preservesValue)
this.methodFlow(source, sourceAp, sink, sinkAp, c, preservesValue)
)
}
@@ -760,7 +760,7 @@ class SystemTextStringBuilderFlow extends LibraryTypeDataFlow, SystemTextStringB
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
Constructor c
) {
c = getAMember() and
c = this.getAMember() and
c.getParameter(0).getType() instanceof StringType and
source = TCallableFlowSourceArg(0) and
sourceAp = AccessPath::empty() and
@@ -894,7 +894,7 @@ class IEnumerableFlow extends LibraryTypeDataFlow, RefType {
) {
preservesValue = true and
(
methodFlowLINQExtensions(source, sourceAp, sink, sinkAp, c)
this.methodFlowLINQExtensions(source, sourceAp, sink, sinkAp, c)
or
c = this.getFind() and
sourceAp = AccessPath::element() and
@@ -1674,14 +1674,14 @@ class SystemConvertFlow extends LibraryTypeDataFlow, SystemConvertClass {
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
methodFlow(source, sink, c) and
this.methodFlow(source, sink, c) and
preservesValue = false
}
private predicate methodFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationMethod m
) {
m = getAMethod() and
m = this.getAMethod() and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
}
@@ -1694,7 +1694,7 @@ class SystemWebHttpCookieFlow extends LibraryTypeDataFlow, SystemWebHttpCookie {
boolean preservesValue
) {
exists(Property p |
propertyFlow(p) and
this.propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
@@ -1703,8 +1703,8 @@ class SystemWebHttpCookieFlow extends LibraryTypeDataFlow, SystemWebHttpCookie {
}
private predicate propertyFlow(Property p) {
p = getValueProperty() or
p = getValuesProperty()
p = this.getValueProperty() or
p = this.getValuesProperty()
}
}
@@ -1715,7 +1715,7 @@ class SystemNetCookieFlow extends LibraryTypeDataFlow, SystemNetCookieClass {
boolean preservesValue
) {
exists(Property p |
propertyFlow(p) and
this.propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
@@ -1733,7 +1733,7 @@ class SystemNetIPHostEntryFlow extends LibraryTypeDataFlow, SystemNetIPHostEntry
boolean preservesValue
) {
exists(Property p |
propertyFlow(p) and
this.propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
@@ -1742,8 +1742,8 @@ class SystemNetIPHostEntryFlow extends LibraryTypeDataFlow, SystemNetIPHostEntry
}
private predicate propertyFlow(Property p) {
p = getHostNameProperty() or
p = getAliasesProperty()
p = this.getHostNameProperty() or
p = this.getAliasesProperty()
}
}
@@ -1755,7 +1755,7 @@ class SystemWebUIWebControlsTextBoxFlow extends LibraryTypeDataFlow,
boolean preservesValue
) {
exists(Property p |
propertyFlow(p) and
this.propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
@@ -1763,7 +1763,7 @@ class SystemWebUIWebControlsTextBoxFlow extends LibraryTypeDataFlow,
preservesValue = false
}
private predicate propertyFlow(Property p) { p = getTextProperty() }
private predicate propertyFlow(Property p) { p = this.getTextProperty() }
}
/** Data flow for `System.Collections.Generic.KeyValuePair`. */
@@ -1864,11 +1864,11 @@ class SystemThreadingTasksTaskFlow extends LibraryTypeDataFlow, SystemThreadingT
SourceDeclarationCallable c, boolean preservesValue
) {
(
constructorFlow(source, sink, c) and
this.constructorFlow(source, sink, c) and
sourceAp = AccessPath::empty() and
sinkAp = AccessPath::empty()
or
methodFlow(source, sourceAp, sink, sinkAp, c)
this.methodFlow(source, sourceAp, sink, sinkAp, c)
) and
preservesValue = true
}
@@ -1954,9 +1954,9 @@ class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow, SystemThreading
SourceDeclarationCallable c, boolean preservesValue
) {
(
constructorFlow(source, sourceAp, sink, sinkAp, c)
this.constructorFlow(source, sourceAp, sink, sinkAp, c)
or
methodFlow(source, sourceAp, sink, sinkAp, c)
this.methodFlow(source, sourceAp, sink, sinkAp, c)
) and
preservesValue = true
or
@@ -2101,14 +2101,14 @@ private class SystemRuntimeCompilerServicesConfiguredTaskAwaitableTFlow extends
class SystemThreadingTasksFactoryFlow extends LibraryTypeDataFlow {
SystemThreadingTasksFactoryFlow() {
this instanceof SystemThreadingTasksClass and
getName().regexpMatch("TaskFactory(<>)?")
this.getName().regexpMatch("TaskFactory(<>)?")
}
override predicate callableFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
methodFlow(source, sourceAp, sink, sinkAp, c) and
this.methodFlow(source, sourceAp, sink, sinkAp, c) and
preservesValue = true
}
@@ -2236,12 +2236,12 @@ library class SystemTextEncodingFlow extends LibraryTypeDataFlow, SystemTextEnco
preservesValue = false and
c = this.getAMethod() and
exists(Method m | m.getAnOverrider*().getUnboundDeclaration() = c |
m = getGetBytesMethod() and
m = this.getGetBytesMethod() and
source = getFlowSourceArg(m, 0, sourceAp) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty()
or
m = [getGetStringMethod(), getGetCharsMethod()] and
m = [this.getGetStringMethod(), this.getGetCharsMethod()] and
source = TCallableFlowSourceArg(0) and
sourceAp = AccessPath::element() and
sink = TCallableFlowSinkReturn() and
@@ -2257,9 +2257,9 @@ library class SystemIOMemoryStreamFlow extends LibraryTypeDataFlow, SystemIOMemo
boolean preservesValue
) {
(
constructorFlow(source, sink, c)
this.constructorFlow(source, sink, c)
or
c = getToArrayMethod().getAnOverrider*() and
c = this.getToArrayMethod().getAnOverrider*() and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn()
) and
@@ -2267,7 +2267,7 @@ library class SystemIOMemoryStreamFlow extends LibraryTypeDataFlow, SystemIOMemo
}
private predicate constructorFlow(CallableFlowSource source, CallableFlowSink sink, Constructor c) {
c = getAMember() and
c = this.getAMember() and
c.getParameter(0).getType().(ArrayType).getElementType() instanceof ByteType and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
@@ -2281,17 +2281,17 @@ class SystemIOStreamFlow extends LibraryTypeDataFlow, SystemIOStreamClass {
boolean preservesValue
) {
(
c = getAReadMethod().getAnOverrider*() and
c = this.getAReadMethod().getAnOverrider*() and
c.getParameter(0).getType().(ArrayType).getElementType() instanceof ByteType and
sink = TCallableFlowSinkArg(0) and
source = TCallableFlowSourceQualifier()
or
c = getAWriteMethod().getAnOverrider*() and
c = this.getAWriteMethod().getAnOverrider*() and
c.getParameter(0).getType().(ArrayType).getElementType() instanceof ByteType and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkQualifier()
or
c = any(Method m | m = getAMethod() and m.getName().matches("CopyTo%")).getAnOverrider*() and
c = any(Method m | m = this.getAMethod() and m.getName().matches("CopyTo%")).getAnOverrider*() and
c.getParameter(0).getType() instanceof SystemIOStreamClass and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkArg(0)
@@ -2307,12 +2307,12 @@ class SystemIOCompressionDeflateStreamFlow extends LibraryTypeDataFlow,
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
constructorFlow(source, sink, c) and
this.constructorFlow(source, sink, c) and
preservesValue = false
}
private predicate constructorFlow(CallableFlowSource source, CallableFlowSink sink, Constructor c) {
c = getAMember() and
c = this.getAMember() and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
}
@@ -2324,7 +2324,7 @@ class SystemXmlXmlReaderFlow extends LibraryTypeDataFlow, SystemXmlXmlReaderClas
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
c = getCreateMethod() and
c = this.getCreateMethod() and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn() and
preservesValue = false
@@ -2337,7 +2337,7 @@ class SystemXmlXmlDocumentFlow extends LibraryTypeDataFlow, SystemXmlXmlDocument
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
c = getLoadMethod() and
c = this.getLoadMethod() and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkQualifier() and
preservesValue = false
@@ -2352,13 +2352,13 @@ class SystemXmlXmlNodeFlow extends LibraryTypeDataFlow, SystemXmlXmlNodeClass {
) {
(
exists(Property p |
p = getAProperty() and
p = this.getAProperty() and
c = p.getGetter() and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn()
)
or
c = getASelectNodeMethod() and
c = this.getASelectNodeMethod() and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn()
) and
@@ -2372,7 +2372,7 @@ class SystemXmlXmlNamedNodeMapFlow extends LibraryTypeDataFlow, SystemXmlXmlName
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
c = getGetNamedItemMethod() and
c = this.getGetNamedItemMethod() and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
preservesValue = true
@@ -2385,14 +2385,14 @@ class SystemIOPathFlow extends LibraryTypeDataFlow, SystemIOPathClass {
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
c = getAMethod("Combine") and
c = this.getAMethod("Combine") and
source = getFlowSourceArg(c, _, sourceAp) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = false
or
exists(Parameter p |
c = getAMethod() and
c = this.getAMethod() and
c.getName().matches("Get%") and
p = c.getAParameter() and
p.hasName("path") and
@@ -2411,10 +2411,10 @@ class SystemWebHttpUtilityFlow extends LibraryTypeDataFlow, SystemWebHttpUtility
boolean preservesValue
) {
(
c = getAnHtmlAttributeEncodeMethod() or
c = getAnHtmlEncodeMethod() or
c = getAJavaScriptStringEncodeMethod() or
c = getAnUrlEncodeMethod()
c = this.getAnHtmlAttributeEncodeMethod() or
c = this.getAnHtmlEncodeMethod() or
c = this.getAJavaScriptStringEncodeMethod() or
c = this.getAnUrlEncodeMethod()
) and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn() and
@@ -2429,8 +2429,8 @@ class SystemWebHttpServerUtilityFlow extends LibraryTypeDataFlow, SystemWebHttpS
boolean preservesValue
) {
(
c = getAnHtmlEncodeMethod() or
c = getAnUrlEncodeMethod()
c = this.getAnHtmlEncodeMethod() or
c = this.getAnUrlEncodeMethod()
) and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn() and
@@ -2445,8 +2445,8 @@ class SystemNetWebUtilityFlow extends LibraryTypeDataFlow, SystemNetWebUtility {
boolean preservesValue
) {
(
c = getAnHtmlEncodeMethod() or
c = getAnUrlEncodeMethod()
c = this.getAnHtmlEncodeMethod() or
c = this.getAnUrlEncodeMethod()
) and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn() and

View File

@@ -76,9 +76,9 @@ module Ssa {
override Callable getEnclosingCallable() { this = SsaImpl::TLocalVar(result, _) }
override string toString() { result = getAssignable().getName() }
override string toString() { result = this.getAssignable().getName() }
override Location getLocation() { result = getAssignable().getLocation() }
override Location getLocation() { result = this.getAssignable().getLocation() }
}
/** A fully qualified field or property. */
@@ -105,7 +105,7 @@ module Ssa {
)
}
override Location getLocation() { result = getFirstAccess().getLocation() }
override Location getLocation() { result = this.getFirstAccess().getLocation() }
}
/** A plain field or property. */
@@ -115,8 +115,8 @@ module Ssa {
override string toString() {
exists(Assignable f, string prefix |
f = getAssignable() and
result = prefix + "." + getAssignable()
f = this.getAssignable() and
result = prefix + "." + this.getAssignable()
|
if f.(Modifiable).isStatic()
then prefix = f.getDeclaringType().getQualifiedName()
@@ -134,7 +134,7 @@ module Ssa {
override SourceVariable getQualifier() { this = SsaImpl::TQualifiedFieldOrProp(_, result, _) }
override string toString() { result = getQualifier() + "." + getAssignable() }
override string toString() { result = this.getQualifier() + "." + this.getAssignable() }
}
}
@@ -611,20 +611,20 @@ module Ssa {
* and which targets the same assignable as this SSA definition.
*/
final AssignableDefinition getAPossibleDefinition() {
exists(Callable setter | SsaImpl::updatesNamedFieldOrProp(_, _, getCall(), _, setter) |
exists(Callable setter | SsaImpl::updatesNamedFieldOrProp(_, _, this.getCall(), _, setter) |
result.getEnclosingCallable() = setter and
result.getTarget() = this.getSourceVariable().getAssignable()
)
or
SsaImpl::updatesCapturedVariable(_, _, getCall(), _, result, _) and
SsaImpl::updatesCapturedVariable(_, _, this.getCall(), _, result, _) and
result.getTarget() = this.getSourceVariable().getAssignable()
}
override string toString() {
result = getToStringPrefix(this) + "SSA call def(" + getSourceVariable() + ")"
result = getToStringPrefix(this) + "SSA call def(" + this.getSourceVariable() + ")"
}
override Location getLocation() { result = getCall().getLocation() }
override Location getLocation() { result = this.getCall().getLocation() }
}
/**
@@ -649,10 +649,10 @@ module Ssa {
final Definition getQualifierDefinition() { result = q }
override string toString() {
result = getToStringPrefix(this) + "SSA qualifier def(" + getSourceVariable() + ")"
result = getToStringPrefix(this) + "SSA qualifier def(" + this.getSourceVariable() + ")"
}
override Location getLocation() { result = getQualifierDefinition().getLocation() }
override Location getLocation() { result = this.getQualifierDefinition().getLocation() }
}
/**
@@ -699,7 +699,7 @@ module Ssa {
}
override string toString() {
result = getToStringPrefix(this) + "SSA phi(" + getSourceVariable() + ")"
result = getToStringPrefix(this) + "SSA phi(" + this.getSourceVariable() + ")"
}
/*

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