diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/EdgeKind.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/EdgeKind.qll index 650c15f189a..3de1d4b6028 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/EdgeKind.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/EdgeKind.qll @@ -17,6 +17,7 @@ private newtype TEdgeKind = * `EdgeKind`. */ abstract class EdgeKind extends TEdgeKind { + /** Gets a textual representation of this edge kind. */ abstract string toString(); } @@ -28,6 +29,10 @@ class GotoEdge extends EdgeKind, TGotoEdge { final override string toString() { result = "Goto" } } +/** + * Gets the single instance of `GotoEdge`, representing the unconditional successor of an + * `Instruction` + */ GotoEdge gotoEdge() { result = TGotoEdge() } /** @@ -38,6 +43,10 @@ class TrueEdge extends EdgeKind, TTrueEdge { final override string toString() { result = "True" } } +/** + * Gets the single instance of `TrueEdge`, representing the successor of a conditional branch when + * the condition is non-zero. + */ TrueEdge trueEdge() { result = TTrueEdge() } /** @@ -48,6 +57,10 @@ class FalseEdge extends EdgeKind, TFalseEdge { final override string toString() { result = "False" } } +/** + * Gets the single instance of `FalseEdge`, representing the successor of a conditional branch when + * the condition is zero. + */ FalseEdge falseEdge() { result = TFalseEdge() } /** @@ -58,6 +71,10 @@ class ExceptionEdge extends EdgeKind, TExceptionEdge { final override string toString() { result = "Exception" } } +/** + * Gets the single instance of `ExceptionEdge`, representing the successor of an instruction when + * that instruction's evaluation throws an exception. + */ ExceptionEdge exceptionEdge() { result = TExceptionEdge() } /** @@ -68,6 +85,10 @@ class DefaultEdge extends EdgeKind, TDefaultEdge { final override string toString() { result = "Default" } } +/** + * Gets the single instance of `DefaultEdge`, representing the successor of a `Switch` instruction + * when none of the case values matches the condition value. + */ DefaultEdge defaultEdge() { result = TDefaultEdge() } /** @@ -91,4 +112,8 @@ class CaseEdge extends EdgeKind, TCaseEdge { string getMaxValue() { result = maxValue } } +/** + * Gets the `CaseEdge` representing the successor of a `Switch` instruction corresponding to the + * `case` label with the specified lower and upper bounds. + */ CaseEdge caseEdge(string minValue, string maxValue) { result = TCaseEdge(minValue, maxValue) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/TempVariableTag.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/TempVariableTag.qll index ec6de78cfa4..384c1849f2d 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/TempVariableTag.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/TempVariableTag.qll @@ -1,6 +1,15 @@ +/** + * 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 +/** + * Describes the 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) } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll index 227b1a34041..dd3a77d5229 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll @@ -1,3 +1,7 @@ +/** + * 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 = @@ -24,10 +28,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 representing the order in which this operand should appear in the operand list + * of an instruction when printing the IR. + */ abstract int getSortOrder(); + /** + * Gets a label that will appear before the operand when printing the IR. + */ string getLabel() { result = "" } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll index d297097abd9..c27701f6acd 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll @@ -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 */ @@ -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 @@ -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 diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll index 6034ebc5674..6d71ca9f798 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll @@ -1,3 +1,15 @@ +/** + * Provides predicates for manipulating integer constants 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; /** diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/EdgeKind.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/EdgeKind.qll index 650c15f189a..3de1d4b6028 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/EdgeKind.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/EdgeKind.qll @@ -17,6 +17,7 @@ private newtype TEdgeKind = * `EdgeKind`. */ abstract class EdgeKind extends TEdgeKind { + /** Gets a textual representation of this edge kind. */ abstract string toString(); } @@ -28,6 +29,10 @@ class GotoEdge extends EdgeKind, TGotoEdge { final override string toString() { result = "Goto" } } +/** + * Gets the single instance of `GotoEdge`, representing the unconditional successor of an + * `Instruction` + */ GotoEdge gotoEdge() { result = TGotoEdge() } /** @@ -38,6 +43,10 @@ class TrueEdge extends EdgeKind, TTrueEdge { final override string toString() { result = "True" } } +/** + * Gets the single instance of `TrueEdge`, representing the successor of a conditional branch when + * the condition is non-zero. + */ TrueEdge trueEdge() { result = TTrueEdge() } /** @@ -48,6 +57,10 @@ class FalseEdge extends EdgeKind, TFalseEdge { final override string toString() { result = "False" } } +/** + * Gets the single instance of `FalseEdge`, representing the successor of a conditional branch when + * the condition is zero. + */ FalseEdge falseEdge() { result = TFalseEdge() } /** @@ -58,6 +71,10 @@ class ExceptionEdge extends EdgeKind, TExceptionEdge { final override string toString() { result = "Exception" } } +/** + * Gets the single instance of `ExceptionEdge`, representing the successor of an instruction when + * that instruction's evaluation throws an exception. + */ ExceptionEdge exceptionEdge() { result = TExceptionEdge() } /** @@ -68,6 +85,10 @@ class DefaultEdge extends EdgeKind, TDefaultEdge { final override string toString() { result = "Default" } } +/** + * Gets the single instance of `DefaultEdge`, representing the successor of a `Switch` instruction + * when none of the case values matches the condition value. + */ DefaultEdge defaultEdge() { result = TDefaultEdge() } /** @@ -91,4 +112,8 @@ class CaseEdge extends EdgeKind, TCaseEdge { string getMaxValue() { result = maxValue } } +/** + * Gets the `CaseEdge` representing the successor of a `Switch` instruction corresponding to the + * `case` label with the specified lower and upper bounds. + */ CaseEdge caseEdge(string minValue, string maxValue) { result = TCaseEdge(minValue, maxValue) } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/TempVariableTag.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/TempVariableTag.qll index ec6de78cfa4..384c1849f2d 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/TempVariableTag.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/TempVariableTag.qll @@ -1,6 +1,15 @@ +/** + * 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 +/** + * Describes the 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) } } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/internal/OperandTag.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/internal/OperandTag.qll index 227b1a34041..dd3a77d5229 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/internal/OperandTag.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/internal/OperandTag.qll @@ -1,3 +1,7 @@ +/** + * 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 = @@ -24,10 +28,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 representing the order in which this operand should appear in the operand list + * of an instruction when printing the IR. + */ abstract int getSortOrder(); + /** + * Gets a label that will appear before the operand when printing the IR. + */ string getLabel() { result = "" } } diff --git a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll index 6034ebc5674..6d71ca9f798 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll @@ -1,3 +1,15 @@ +/** + * Provides predicates for manipulating integer constants 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; /**