Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
485 changes: 485 additions & 0 deletions cpp/ql/src/semmle/code/cpp/controlflow/IRGuards.qll

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ abstract class PointerOffsetOpcode extends PointerArithmeticOpcode {}

abstract class CompareOpcode extends BinaryOpcode {}

abstract class RelationalOpcode extends CompareOpcode {}

abstract class CopyOpcode extends Opcode {}

abstract class MemoryAccessOpcode extends Opcode {}
Expand Down Expand Up @@ -117,10 +119,10 @@ module Opcode {
class LogicalNot extends UnaryOpcode, TLogicalNot { override final string toString() { result = "LogicalNot" } }
class CompareEQ extends CompareOpcode, TCompareEQ { override final string toString() { result = "CompareEQ" } }
class CompareNE extends CompareOpcode, TCompareNE { override final string toString() { result = "CompareNE" } }
class CompareLT extends CompareOpcode, TCompareLT { override final string toString() { result = "CompareLT" } }
class CompareGT extends CompareOpcode, TCompareGT { override final string toString() { result = "CompareGT" } }
class CompareLE extends CompareOpcode, TCompareLE { override final string toString() { result = "CompareLE" } }
class CompareGE extends CompareOpcode, TCompareGE { override final string toString() { result = "CompareGE" } }
class CompareLT extends RelationalOpcode, TCompareLT { override final string toString() { result = "CompareLT" } }
class CompareGT extends RelationalOpcode, TCompareGT { override final string toString() { result = "CompareGT" } }
class CompareLE extends RelationalOpcode, TCompareLE { override final string toString() { result = "CompareLE" } }
class CompareGE extends RelationalOpcode, TCompareGE { override final string toString() { result = "CompareGE" } }
class PointerAdd extends PointerOffsetOpcode, TPointerAdd { override final string toString() { result = "PointerAdd" } }
class PointerSub extends PointerOffsetOpcode, TPointerSub { override final string toString() { result = "PointerSub" } }
class PointerDiff extends PointerArithmeticOpcode, TPointerDiff { override final string toString() { result = "PointerDiff" } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,12 @@ class IRBlock extends TIRBlock {
dominates(result.getAPredecessor()) and
not strictlyDominates(result)
}

/**
* Holds if this block is reachable from the entry point of its function
*/
final predicate isReachableFromFunctionEntry() {
this = getFunctionIR().getEntryBlock() or
getAPredecessor().isReachableFromFunctionEntry()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,19 @@ class Instruction extends Construction::TInstruction {
}

/**
* Gets the `Expr` whose results is computed by this instruction, if any.
* Gets the `Expr` whose result is computed by this instruction, if any.
*/
final Expr getResultExpression() {
result = Construction::getInstructionResultExpression(this)
final Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}

/**
* Gets the unconverted `Expr` whose result is computed by this instruction, if any.
*/
final Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)
}


/**
* Gets the type of the result produced by this instruction. If the
Expand Down Expand Up @@ -967,28 +975,110 @@ class CompareNEInstruction extends CompareInstruction {
}
}

class CompareLTInstruction extends CompareInstruction {
/**
* Represents an instruction that does a relative comparison of two values, such as `<` or `>=`.
*/
class RelationalInstruction extends CompareInstruction {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that many of the classes in this file are missing QLDoc comments, but please add QLDoc for the new class and its abstract methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added documentation

RelationalInstruction() {
opcode instanceof RelationalOpcode
}
/**
* Gets the operand on the "greater" (or "greater-or-equal") side
* of this relational instruction, that is, the side that is larger
* if the overall instruction evaluates to `true`; for example on
* `x <= 20` this is the `20`, and on `y > 0` it is `y`.
*/
Instruction getGreaterOperand() {
none()
}

/**
* Gets the operand on the "lesser" (or "lesser-or-equal") side
* of this relational instruction, that is, the side that is smaller
* if the overall instruction evaluates to `true`; for example on
* `x <= 20` this is `x`, and on `y > 0` it is the `0`.
*/
Instruction getLesserOperand() {
none()
}
/**
* Holds if this relational instruction is strict (is not an "or-equal" instruction).
*/
predicate isStrict() {
none()
}
}

class CompareLTInstruction extends RelationalInstruction {
CompareLTInstruction() {
opcode instanceof Opcode::CompareLT
}

override Instruction getLesserOperand() {
result = getLeftOperand()
}

override Instruction getGreaterOperand() {
result = getRightOperand()
}

override predicate isStrict() {
any()
}
}

class CompareGTInstruction extends CompareInstruction {
class CompareGTInstruction extends RelationalInstruction {
CompareGTInstruction() {
opcode instanceof Opcode::CompareGT
}

override Instruction getLesserOperand() {
result = getRightOperand()
}

override Instruction getGreaterOperand() {
result = getLeftOperand()
}

override predicate isStrict() {
any()
}
}

class CompareLEInstruction extends CompareInstruction {
class CompareLEInstruction extends RelationalInstruction {
CompareLEInstruction() {
opcode instanceof Opcode::CompareLE
}

override Instruction getLesserOperand() {
result = getLeftOperand()
}

override Instruction getGreaterOperand() {
result = getRightOperand()
}

override predicate isStrict() {
none()
}
}

class CompareGEInstruction extends CompareInstruction {
class CompareGEInstruction extends RelationalInstruction {
CompareGEInstruction() {
opcode instanceof Opcode::CompareGE
}

override Instruction getLesserOperand() {
result = getRightOperand()
}

override Instruction getGreaterOperand() {
result = getLeftOperand()
}

override predicate isStrict() {
none()
}
}

class SwitchInstruction extends Instruction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,12 @@ cached private module Cached {
)
}

cached Expr getInstructionResultExpression(Instruction instruction) {
result = getOldInstruction(instruction).getResultExpression()
cached Expr getInstructionConvertedResultExpression(Instruction instruction) {
result = getOldInstruction(instruction).getConvertedResultExpression()
}

cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
result = getOldInstruction(instruction).getUnconvertedResultExpression()
}

cached Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
Expand Down
8 changes: 8 additions & 0 deletions cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,12 @@ class IRBlock extends TIRBlock {
dominates(result.getAPredecessor()) and
not strictlyDominates(result)
}

/**
* Holds if this block is reachable from the entry point of its function
*/
final predicate isReachableFromFunctionEntry() {
this = getFunctionIR().getEntryBlock() or
getAPredecessor().isReachableFromFunctionEntry()
}
}
104 changes: 97 additions & 7 deletions cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,19 @@ class Instruction extends Construction::TInstruction {
}

/**
* Gets the `Expr` whose results is computed by this instruction, if any.
* Gets the `Expr` whose result is computed by this instruction, if any.
*/
final Expr getResultExpression() {
result = Construction::getInstructionResultExpression(this)
final Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}

/**
* Gets the unconverted `Expr` whose result is computed by this instruction, if any.
*/
final Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)
}


/**
* Gets the type of the result produced by this instruction. If the
Expand Down Expand Up @@ -967,28 +975,110 @@ class CompareNEInstruction extends CompareInstruction {
}
}

class CompareLTInstruction extends CompareInstruction {
/**
* Represents an instruction that does a relative comparison of two values, such as `<` or `>=`.
*/
class RelationalInstruction extends CompareInstruction {
RelationalInstruction() {
opcode instanceof RelationalOpcode
}
/**
* Gets the operand on the "greater" (or "greater-or-equal") side
* of this relational instruction, that is, the side that is larger
* if the overall instruction evaluates to `true`; for example on
* `x <= 20` this is the `20`, and on `y > 0` it is `y`.
*/
Instruction getGreaterOperand() {
none()
}

/**
* Gets the operand on the "lesser" (or "lesser-or-equal") side
* of this relational instruction, that is, the side that is smaller
* if the overall instruction evaluates to `true`; for example on
* `x <= 20` this is `x`, and on `y > 0` it is the `0`.
*/
Instruction getLesserOperand() {
none()
}
/**
* Holds if this relational instruction is strict (is not an "or-equal" instruction).
*/
predicate isStrict() {
none()
}
}

class CompareLTInstruction extends RelationalInstruction {
CompareLTInstruction() {
opcode instanceof Opcode::CompareLT
}

override Instruction getLesserOperand() {
result = getLeftOperand()
}

override Instruction getGreaterOperand() {
result = getRightOperand()
}

override predicate isStrict() {
any()
}
}

class CompareGTInstruction extends CompareInstruction {
class CompareGTInstruction extends RelationalInstruction {
CompareGTInstruction() {
opcode instanceof Opcode::CompareGT
}

override Instruction getLesserOperand() {
result = getRightOperand()
}

override Instruction getGreaterOperand() {
result = getLeftOperand()
}

override predicate isStrict() {
any()
}
}

class CompareLEInstruction extends CompareInstruction {
class CompareLEInstruction extends RelationalInstruction {
CompareLEInstruction() {
opcode instanceof Opcode::CompareLE
}

override Instruction getLesserOperand() {
result = getLeftOperand()
}

override Instruction getGreaterOperand() {
result = getRightOperand()
}

override predicate isStrict() {
none()
}
}

class CompareGEInstruction extends CompareInstruction {
class CompareGEInstruction extends RelationalInstruction {
CompareGEInstruction() {
opcode instanceof Opcode::CompareGE
}

override Instruction getLesserOperand() {
result = getRightOperand()
}

override Instruction getGreaterOperand() {
result = getLeftOperand()
}

override predicate isStrict() {
none()
}
}

class SwitchInstruction extends Instruction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,25 @@ cached private module Cached {
none()
}

cached Expr getInstructionResultExpression(Instruction instruction) {
cached Expr getInstructionConvertedResultExpression(Instruction instruction) {
exists(TranslatedExpr translatedExpr |
translatedExpr = getTranslatedExpr(result) and
instruction = translatedExpr.getResult()
)
}

cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
exists(Expr converted, TranslatedExpr translatedExpr |
result = converted.(Conversion).getExpr+()
or
result = converted
|
not result instanceof Conversion and
translatedExpr = getTranslatedExpr(converted) and
instruction = translatedExpr.getResult()
)
}

cached Instruction getInstructionOperand(Instruction instruction, OperandTag tag) {
result = getInstructionTranslatedElement(instruction).getInstructionOperand(
instruction.getTag(), tag)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,12 @@ class IRBlock extends TIRBlock {
dominates(result.getAPredecessor()) and
not strictlyDominates(result)
}

/**
* Holds if this block is reachable from the entry point of its function
*/
final predicate isReachableFromFunctionEntry() {
this = getFunctionIR().getEntryBlock() or
getAPredecessor().isReachableFromFunctionEntry()
}
}
Loading