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
57 changes: 46 additions & 11 deletions cpp/ql/src/semmle/code/cpp/ir/implementation/EdgeKind.qll
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ private newtype TEdgeKind =
* `EdgeKind`.
*/
abstract class EdgeKind extends TEdgeKind {
/** Gets a textual representation of this edge kind. */
abstract string toString();
}

Expand All @@ -28,8 +29,6 @@ class GotoEdge extends EdgeKind, TGotoEdge {
final override string toString() { result = "Goto" }
}

GotoEdge gotoEdge() { result = TGotoEdge() }

/**
* A "true" edge, representing the successor of a conditional branch when the
* condition is non-zero.
Expand All @@ -38,8 +37,6 @@ class TrueEdge extends EdgeKind, TTrueEdge {
final override string toString() { result = "True" }
}

TrueEdge trueEdge() { result = TTrueEdge() }

/**
* A "false" edge, representing the successor of a conditional branch when the
* condition is zero.
Expand All @@ -48,8 +45,6 @@ class FalseEdge extends EdgeKind, TFalseEdge {
final override string toString() { result = "False" }
}

FalseEdge falseEdge() { result = TFalseEdge() }

/**
* An "exception" edge, representing the successor of an instruction when that
* instruction's evaluation throws an exception.
Expand All @@ -58,8 +53,6 @@ class ExceptionEdge extends EdgeKind, TExceptionEdge {
final override string toString() { result = "Exception" }
}

ExceptionEdge exceptionEdge() { result = TExceptionEdge() }

/**
* A "default" edge, representing the successor of a `Switch` instruction when
* none of the case values matches the condition value.
Expand All @@ -68,8 +61,6 @@ class DefaultEdge extends EdgeKind, TDefaultEdge {
final override string toString() { result = "Default" }
}

DefaultEdge defaultEdge() { result = TDefaultEdge() }

/**
* A "case" edge, representing the successor of a `Switch` instruction when the
* the condition value matches a correponding `case` label.
Expand All @@ -91,4 +82,48 @@ class CaseEdge extends EdgeKind, TCaseEdge {
string getMaxValue() { result = maxValue }
}

CaseEdge caseEdge(string minValue, string maxValue) { result = TCaseEdge(minValue, maxValue) }
/**
* Predicates to access the single instance of each `EdgeKind` class.
*/
module EdgeKind {
/**
* Gets the single instance of the `GotoEdge` class.
*/
GotoEdge gotoEdge() { result = TGotoEdge() }

/**
* Gets the single instance of the `TrueEdge` class.
*/
TrueEdge trueEdge() { result = TTrueEdge() }

/**
* Gets the single instance of the `FalseEdge` class.
*/
FalseEdge falseEdge() { result = TFalseEdge() }

/**
* Gets the single instance of the `ExceptionEdge` class.
*/
ExceptionEdge exceptionEdge() { result = TExceptionEdge() }

/**
* Gets the single instance of the `DefaultEdge` class.
*/
DefaultEdge defaultEdge() { result = TDefaultEdge() }

/**
* Gets the `CaseEdge` representing a `case` label with the specified lower and upper bounds.
* For example:
* ```
* switch (x) {
* case 1: // Edge kind is `caseEdge("1", "1")`
* return x;
* case 2...8: // Edge kind is `caseEdge("2", "8")`
* return x - 1;
* default: // Edge kind is `defaultEdge()`
* return 0;
* }
* ```
*/
CaseEdge caseEdge(string minValue, string maxValue) { result = TCaseEdge(minValue, maxValue) }
}
10 changes: 10 additions & 0 deletions cpp/ql/src/semmle/code/cpp/ir/implementation/TempVariableTag.qll
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
/**
* Defines the public interface to temporary variable tags, which describe the reason a particular
* `IRTempVariable` was generated.
*/

private import internal.TempVariableTagInternal
private import Imports::TempVariableTag

/**
* A reason that a particular IR temporary variable was generated. For example, it could be
* generated to hold the return value of a function, or to hold the result of a `?:` operator
* computed on each branch. The set of possible `TempVariableTag`s is language-dependent.
*/
class TempVariableTag extends TTempVariableTag {
string toString() { result = getTempVariableTagId(this) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -584,9 +584,9 @@ class ConditionalBranchInstruction extends Instruction {

final Instruction getCondition() { result = getConditionOperand().getDef() }

final Instruction getTrueSuccessor() { result = getSuccessor(trueEdge()) }
final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }

final Instruction getFalseSuccessor() { result = getSuccessor(falseEdge()) }
final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
}

class ExitFunctionInstruction extends Instruction {
Expand Down Expand Up @@ -906,7 +906,7 @@ class SwitchInstruction extends Instruction {

final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }

final Instruction getDefaultSuccessor() { result = getSuccessor(defaultEdge()) }
final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Defines the set of possible `OperandTag`s, which are used to identify the role each `Operand`
* plays in the evaluation of its `Instruction`.
*/

private import OperandTagInternal

private newtype TOperandTag =
Expand All @@ -24,10 +29,18 @@ private newtype TOperandTag =
* an `Instruction` is determined by the instruction's opcode.
*/
abstract class OperandTag extends TOperandTag {
/** Gets a textual representation of this operand tag */
abstract string toString();

/**
* Gets an integer that represents where this this operand will appear in the operand list of an
* instruction when the IR is printed.
*/
abstract int getSortOrder();

/**
* Gets a label that will appear before the operand when the IR is printed.
*/
string getLabel() { result = "" }
}

Expand All @@ -47,7 +60,7 @@ abstract class RegisterOperandTag extends OperandTag { }
abstract class TypedOperandTag extends MemoryOperandTag { }

// Note: individual subtypes are listed in the order that the operands should
// appear in the operand list of the instruction when printing.
// appear in the operand list of the instruction when the IR is printed.
/**
* The address operand of an instruction that loads or stores a value from
* memory (e.g. `Load`, `Store`, `InitializeParameter`, `IndirectReadSideEffect`).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -584,9 +584,9 @@ class ConditionalBranchInstruction extends Instruction {

final Instruction getCondition() { result = getConditionOperand().getDef() }

final Instruction getTrueSuccessor() { result = getSuccessor(trueEdge()) }
final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }

final Instruction getFalseSuccessor() { result = getSuccessor(falseEdge()) }
final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
}

class ExitFunctionInstruction extends Instruction {
Expand Down Expand Up @@ -906,7 +906,7 @@ class SwitchInstruction extends Instruction {

final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }

final Instruction getDefaultSuccessor() { result = getSuccessor(defaultEdge()) }
final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ class TranslatedAllocationSideEffects extends TranslatedSideEffects,

override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind = gotoEdge() and
kind = EdgeKind::gotoEdge() and
if exists(getChild(0))
then result = getChild(0).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ class TranslatedReadEffect extends TranslatedElement, TTranslatedReadEffect {

override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind edge) {
tag = OnlyInstructionTag() and
edge = gotoEdge() and
edge = EdgeKind::gotoEdge() and
result = getParent().getChildSuccessor(this)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -584,9 +584,9 @@ class ConditionalBranchInstruction extends Instruction {

final Instruction getCondition() { result = getConditionOperand().getDef() }

final Instruction getTrueSuccessor() { result = getSuccessor(trueEdge()) }
final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }

final Instruction getFalseSuccessor() { result = getSuccessor(falseEdge()) }
final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
}

class ExitFunctionInstruction extends Instruction {
Expand Down Expand Up @@ -906,7 +906,7 @@ class SwitchInstruction extends Instruction {

final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }

final Instruction getDefaultSuccessor() { result = getSuccessor(defaultEdge()) }
final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
}

/**
Expand Down
8 changes: 8 additions & 0 deletions cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ private newtype TCppType =
* of a `VariableAddress` where the variable is of reference type)
*/
class CppType extends TCppType {
/** Gets a textual representation of this type. */
string toString() { none() }

/** Gets a string used in IR dumps */
Expand All @@ -224,6 +225,10 @@ class CppType extends TCppType {
*/
predicate hasType(Type type, boolean isGLValue) { none() }

/**
* Holds if this type represents the C++ type `type`. If `isGLValue` is `true`, then this type
* represents a glvalue of type `type`. Otherwise, it represents a prvalue of type `type`.
*/
final predicate hasUnspecifiedType(Type type, boolean isGLValue) {
exists(Type specifiedType |
hasType(specifiedType, isGLValue) and
Expand Down Expand Up @@ -540,6 +545,9 @@ string getOpaqueTagIdentityString(Type tag) {
}

module LanguageTypeSanity {
/**
* Sanity query to detect C++ `Type` objects which have no corresponding `CppType` object.
*/
query predicate missingCppType(Type type, string message) {
not exists(getTypeForPRValue(type)) and
exists(type.getSize()) and
Expand Down
12 changes: 12 additions & 0 deletions cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
/**
* Provides predicates for manipulating integer constants that are tracked by constant folding and
* similar analyses.
*/

/**
* An alias used to represent the constant value of an integer, if one can be determined. If no
* single constant value can be determined, or if the constant value is out of the representable
* range, it will be represented as the special value `unknown()`. This allows `IntValue` to be used
* in contexts where there must always be a value for the `IntValue`, even if no constant value is
* known.
*/
class IntValue = int;

/**
Expand Down
57 changes: 46 additions & 11 deletions csharp/ql/src/semmle/code/csharp/ir/implementation/EdgeKind.qll
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ private newtype TEdgeKind =
* `EdgeKind`.
*/
abstract class EdgeKind extends TEdgeKind {
/** Gets a textual representation of this edge kind. */
abstract string toString();
}

Expand All @@ -28,8 +29,6 @@ class GotoEdge extends EdgeKind, TGotoEdge {
final override string toString() { result = "Goto" }
}

GotoEdge gotoEdge() { result = TGotoEdge() }

/**
* A "true" edge, representing the successor of a conditional branch when the
* condition is non-zero.
Expand All @@ -38,8 +37,6 @@ class TrueEdge extends EdgeKind, TTrueEdge {
final override string toString() { result = "True" }
}

TrueEdge trueEdge() { result = TTrueEdge() }

/**
* A "false" edge, representing the successor of a conditional branch when the
* condition is zero.
Expand All @@ -48,8 +45,6 @@ class FalseEdge extends EdgeKind, TFalseEdge {
final override string toString() { result = "False" }
}

FalseEdge falseEdge() { result = TFalseEdge() }

/**
* An "exception" edge, representing the successor of an instruction when that
* instruction's evaluation throws an exception.
Expand All @@ -58,8 +53,6 @@ class ExceptionEdge extends EdgeKind, TExceptionEdge {
final override string toString() { result = "Exception" }
}

ExceptionEdge exceptionEdge() { result = TExceptionEdge() }

/**
* A "default" edge, representing the successor of a `Switch` instruction when
* none of the case values matches the condition value.
Expand All @@ -68,8 +61,6 @@ class DefaultEdge extends EdgeKind, TDefaultEdge {
final override string toString() { result = "Default" }
}

DefaultEdge defaultEdge() { result = TDefaultEdge() }

/**
* A "case" edge, representing the successor of a `Switch` instruction when the
* the condition value matches a correponding `case` label.
Expand All @@ -91,4 +82,48 @@ class CaseEdge extends EdgeKind, TCaseEdge {
string getMaxValue() { result = maxValue }
}

CaseEdge caseEdge(string minValue, string maxValue) { result = TCaseEdge(minValue, maxValue) }
/**
* Predicates to access the single instance of each `EdgeKind` class.
*/
module EdgeKind {
/**
* Gets the single instance of the `GotoEdge` class.
*/
GotoEdge gotoEdge() { result = TGotoEdge() }

/**
* Gets the single instance of the `TrueEdge` class.
*/
TrueEdge trueEdge() { result = TTrueEdge() }

/**
* Gets the single instance of the `FalseEdge` class.
*/
FalseEdge falseEdge() { result = TFalseEdge() }

/**
* Gets the single instance of the `ExceptionEdge` class.
*/
ExceptionEdge exceptionEdge() { result = TExceptionEdge() }

/**
* Gets the single instance of the `DefaultEdge` class.
*/
DefaultEdge defaultEdge() { result = TDefaultEdge() }

/**
* Gets the `CaseEdge` representing a `case` label with the specified lower and upper bounds.
* For example:
* ```
* switch (x) {
* case 1: // Edge kind is `caseEdge("1", "1")`
* return x;
* case 2...8: // Edge kind is `caseEdge("2", "8")`
* return x - 1;
* default: // Edge kind is `defaultEdge()`
* return 0;
* }
* ```
*/
CaseEdge caseEdge(string minValue, string maxValue) { result = TCaseEdge(minValue, maxValue) }
}
Loading