C++/C#: Rename `sanity` -> `consistency`

I did both of these languages together because they share some of the changed code via `identical-files.json`.
This commit is contained in:
Dave Bartolomeo 2020-05-11 13:29:52 -04:00
Родитель 86a774d912
Коммит 09d1da2f7a
109 изменённых файлов: 500 добавлений и 500 удалений

Просмотреть файл

@ -111,12 +111,12 @@
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IR.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IR.qll"
],
"IR IRSanity": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRSanity.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRSanity.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRSanity.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRSanity.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRSanity.qll"
"IR IRConsistency": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRConsistency.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRConsistency.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRConsistency.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRConsistency.qll"
],
"IR PrintIR": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll",
@ -157,10 +157,10 @@
"cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll"
],
"IR SSASanity": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll"
"IR SSAConsistency": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll"
],
"C++ IR InstructionImports": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionImports.qll",

Просмотреть файл

@ -0,0 +1,9 @@
/**
* @name AST Consistency Check
* @description Performs consistency checks on the Abstract Syntax Tree. This query should have no results.
* @kind table
* @id cpp/ast-consistency-check
*/
import cpp
import CastConsistency

Просмотреть файл

@ -1,9 +0,0 @@
/**
* @name AST Sanity Check
* @description Performs sanity checks on the Abstract Syntax Tree. This query should have no results.
* @kind table
* @id cpp/ast-sanity-check
*/
import cpp
import CastSanity

Просмотреть файл

@ -48,10 +48,10 @@ class Cast extends Conversion, @cast {
/**
* INTERNAL: Do not use.
* Query predicates used to check invariants that should hold for all `Cast`
* nodes. To run all sanity queries for the ASTs, including the ones below,
* run "semmle/code/cpp/ASTSanity.ql".
* nodes. To run all consistency queries for the ASTs, including the ones below,
* run "semmle/code/cpp/ASTConsistency.ql".
*/
module CastSanity {
module CastConsistency {
query predicate multipleSemanticConversionStrings(Cast cast, Type fromType, string kind) {
// Every cast should have exactly one semantic conversion kind
count(cast.getSemanticConversionString()) > 1 and

Просмотреть файл

@ -0,0 +1,8 @@
/**
* @name IR Consistency Check
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id cpp/ir-consistency-check
*/
import implementation.aliased_ssa.IRConsistency

Просмотреть файл

@ -1,8 +0,0 @@
/**
* @name IR Sanity Check
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id cpp/ir-sanity-check
*/
import implementation.aliased_ssa.IRSanity

Просмотреть файл

@ -275,7 +275,7 @@ class IROpaqueType extends IRSizedType, TIROpaqueType {
final override int getByteSize() { result = byteSize }
}
module IRTypeSanity {
module IRTypeConsistency {
query predicate missingCanonicalLanguageType(IRType type, string message) {
not exists(type.getCanonicalLanguageType()) and
message = "Type does not have a canonical `LanguageType`"
@ -300,5 +300,5 @@ module IRTypeSanity {
concat(type.getIRType().toString(), ", ")
}
import Language::LanguageTypeSanity
import Language::LanguageTypeConsistency
}

Просмотреть файл

@ -0,0 +1,8 @@
/**
* @name Aliased SSA IR Consistency Check
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id cpp/aliased-ssa-ir-consistency-check
*/
import IRConsistency

Просмотреть файл

@ -1,8 +1,8 @@
private import IR
import InstructionSanity // module is below
import IRTypeSanity // module is in IRType.qll
import InstructionConsistency // module is below
import IRTypeConsistency // module is in IRType.qll
module InstructionSanity {
module InstructionConsistency {
private import internal.InstructionImports as Imports
private import Imports::OperandTag
private import Imports::Overlap

Просмотреть файл

@ -1,8 +0,0 @@
/**
* @name Aliased SSA IR Sanity Check
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id cpp/aliased-ssa-ir-sanity-check
*/
import IRSanity

Просмотреть файл

@ -0,0 +1,8 @@
/**
* @name Aliased SSA Consistency Check
* @description Performs consistency checks on the SSA construction. This query should have no results.
* @kind table
* @id cpp/aliased-ssa-consistency-check
*/
import SSAConsistency

Просмотреть файл

@ -1,2 +1,2 @@
private import SSAConstruction as SSA
import SSA::SSASanity
import SSA::SSAConsistency

Просмотреть файл

@ -941,7 +941,7 @@ private module CachedForDebugging {
}
}
module SSASanity {
module SSAConsistency {
query predicate multipleOperandMemoryLocations(
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
) {

Просмотреть файл

@ -1,8 +0,0 @@
/**
* @name Aliased SSA Sanity Check
* @description Performs sanity checks on the SSA construction. This query should have no results.
* @kind table
* @id cpp/aliased-ssa-sanity-check
*/
import SSASanity

Просмотреть файл

@ -0,0 +1,8 @@
/**
* @name Raw IR Consistency Check
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id cpp/raw-ir-consistency-check
*/
import IRConsistency

Просмотреть файл

@ -1,8 +1,8 @@
private import IR
import InstructionSanity // module is below
import IRTypeSanity // module is in IRType.qll
import InstructionConsistency // module is below
import IRTypeConsistency // module is in IRType.qll
module InstructionSanity {
module InstructionConsistency {
private import internal.InstructionImports as Imports
private import Imports::OperandTag
private import Imports::Overlap

Просмотреть файл

@ -1,8 +0,0 @@
/**
* @name Raw IR Sanity Check
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id cpp/raw-ir-sanity-check
*/
import IRSanity

Просмотреть файл

@ -0,0 +1,8 @@
/**
* @name SSA IR Consistency Check
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id cpp/ssa-ir-consistency-check
*/
import IRConsistency

Просмотреть файл

@ -1,8 +1,8 @@
private import IR
import InstructionSanity // module is below
import IRTypeSanity // module is in IRType.qll
import InstructionConsistency // module is below
import IRTypeConsistency // module is in IRType.qll
module InstructionSanity {
module InstructionConsistency {
private import internal.InstructionImports as Imports
private import Imports::OperandTag
private import Imports::Overlap

Просмотреть файл

@ -1,8 +0,0 @@
/**
* @name SSA IR Sanity Check
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id cpp/ssa-ir-sanity-check
*/
import IRSanity

Просмотреть файл

@ -0,0 +1,8 @@
/**
* @name Unaliased SSA Consistency Check
* @description Performs consistency checks on the SSA construction. This query should have no results.
* @kind table
* @id cpp/unaliased-ssa-consistency-check
*/
import SSAConsistency

Просмотреть файл

@ -1,2 +1,2 @@
private import SSAConstruction as SSA
import SSA::SSASanity
import SSA::SSAConsistency

Просмотреть файл

@ -941,7 +941,7 @@ private module CachedForDebugging {
}
}
module SSASanity {
module SSAConsistency {
query predicate multipleOperandMemoryLocations(
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
) {

Просмотреть файл

@ -1,8 +0,0 @@
/**
* @name Unaliased SSA Sanity Check
* @description Performs sanity checks on the SSA construction. This query should have no results.
* @kind table
* @id cpp/unaliased-ssa-sanity-check
*/
import SSASanity

Просмотреть файл

@ -544,9 +544,9 @@ string getOpaqueTagIdentityString(Type tag) {
result = getTypeIdentityString(tag)
}
module LanguageTypeSanity {
module LanguageTypeConsistency {
/**
* Sanity query to detect C++ `Type` objects which have no corresponding `CppType` object.
* Consistency query to detect C++ `Type` objects which have no corresponding `CppType` object.
*/
query predicate missingCppType(Type type, string message) {
not exists(getTypeForPRValue(type)) and

Просмотреть файл

@ -1,14 +1,14 @@
/**
* @name Padding Sanity Check
* @description Performs sanity checks for the padding library. This query should have no results.
* @name Padding Consistency Check
* @description Performs consistency checks for the padding library. This query should have no results.
* @kind table
* @id cpp/padding-sanity-check
* @id cpp/padding-consistency-check
*/
import Padding
/*
* Sanity-check: Find discrepancies between computed and actual size on LP64.
* Consistency-check: Find discrepancies between computed and actual size on LP64.
*/
/*

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ASTConsistency.ql

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ASTSanity.ql

Просмотреть файл

@ -0,0 +1,2 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IRConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/IRConsistency.ql

Просмотреть файл

@ -1,2 +0,0 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IRSanity
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/IRSanity.ql

Просмотреть файл

@ -1,2 +1,2 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSASanity
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.ql

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/raw/IRConsistency.ql

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/raw/IRSanity.ql

Просмотреть файл

@ -0,0 +1,2 @@
import semmle.code.cpp.ir.implementation.unaliased_ssa.IRConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.ql

Просмотреть файл

@ -1,2 +0,0 @@
import semmle.code.cpp.ir.implementation.unaliased_ssa.IRSanity
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/IRSanity.ql

Просмотреть файл

@ -1,2 +1,2 @@
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSASanity
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.ql

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql

Просмотреть файл

@ -0,0 +1,2 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IRConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/IRConsistency.ql

Просмотреть файл

@ -1,2 +0,0 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IRSanity
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/IRSanity.ql

Просмотреть файл

@ -1,2 +1,2 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSASanity
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.ql

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql

Просмотреть файл

@ -0,0 +1,2 @@
import semmle.code.cpp.ir.implementation.unaliased_ssa.IRConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.ql

Просмотреть файл

@ -1,2 +0,0 @@
import semmle.code.cpp.ir.implementation.unaliased_ssa.IRSanity
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/IRSanity.ql

Просмотреть файл

@ -1,2 +1,2 @@
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSASanity
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.ql

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/IRConsistency.ql

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/IRSanity.ql

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/raw/IRConsistency.ql

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/raw/IRSanity.ql

Просмотреть файл

@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.ql

Просмотреть файл

@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/IRSanity.ql

Просмотреть файл

@ -0,0 +1,8 @@
/**
* @name IR Consistency Check
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id csharp/ir-consistency-check
*/
import implementation.raw.IRConsistency

Просмотреть файл

@ -1,8 +0,0 @@
/**
* @name IR Sanity Check
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id csharp/ir-sanity-check
*/
import implementation.raw.IRSanity

Просмотреть файл

@ -275,7 +275,7 @@ class IROpaqueType extends IRSizedType, TIROpaqueType {
final override int getByteSize() { result = byteSize }
}
module IRTypeSanity {
module IRTypeConsistency {
query predicate missingCanonicalLanguageType(IRType type, string message) {
not exists(type.getCanonicalLanguageType()) and
message = "Type does not have a canonical `LanguageType`"
@ -300,5 +300,5 @@ module IRTypeSanity {
concat(type.getIRType().toString(), ", ")
}
import Language::LanguageTypeSanity
import Language::LanguageTypeConsistency
}

Просмотреть файл

@ -0,0 +1,8 @@
/**
* @name Raw IR Consistency Check
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id csharp/raw-ir-consistency-check
*/
import IRConsistency

Просмотреть файл

@ -1,8 +1,8 @@
private import IR
import InstructionSanity // module is below
import IRTypeSanity // module is in IRType.qll
import InstructionConsistency // module is below
import IRTypeConsistency // module is in IRType.qll
module InstructionSanity {
module InstructionConsistency {
private import internal.InstructionImports as Imports
private import Imports::OperandTag
private import Imports::Overlap

Просмотреть файл

@ -1,8 +0,0 @@
/**
* @name Raw IR Sanity Check
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id csharp/raw-ir-sanity-check
*/
import IRSanity

Просмотреть файл

@ -0,0 +1,8 @@
/**
* @name SSA IR Consistency Check
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id cpp/ssa-ir-consistency-check
*/
import IRConsistency

Просмотреть файл

@ -0,0 +1,340 @@
private import IR
import InstructionConsistency // module is below
import IRTypeConsistency // module is in IRType.qll
module InstructionConsistency {
private import internal.InstructionImports as Imports
private import Imports::OperandTag
private import Imports::Overlap
private import internal.IRInternal
/**
* Holds if instruction `instr` is missing an expected operand with tag `tag`.
*/
query predicate missingOperand(Instruction instr, string message, IRFunction func, string funcText) {
exists(OperandTag tag |
instr.getOpcode().hasOperand(tag) and
not exists(NonPhiOperand operand |
operand = instr.getAnOperand() and
operand.getOperandTag() = tag
) and
message =
"Instruction '" + instr.getOpcode().toString() +
"' is missing an expected operand with tag '" + tag.toString() + "' in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
}
/**
* Holds if instruction `instr` has an unexpected operand with tag `tag`.
*/
query predicate unexpectedOperand(Instruction instr, OperandTag tag) {
exists(NonPhiOperand operand |
operand = instr.getAnOperand() and
operand.getOperandTag() = tag
) and
not instr.getOpcode().hasOperand(tag) and
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
not (
instr instanceof BuiltInOperationInstruction and tag instanceof PositionalArgumentOperandTag
) and
not (instr instanceof InlineAsmInstruction and tag instanceof AsmOperandTag)
}
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
query predicate duplicateOperand(
Instruction instr, string message, IRFunction func, string funcText
) {
exists(OperandTag tag, int operandCount |
operandCount =
strictcount(NonPhiOperand operand |
operand = instr.getAnOperand() and
operand.getOperandTag() = tag
) and
operandCount > 1 and
not tag instanceof UnmodeledUseOperandTag and
message =
"Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
" in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
}
/**
* Holds if `Phi` instruction `instr` is missing an operand corresponding to
* the predecessor block `pred`.
*/
query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
pred = instr.getBlock().getAPredecessor() and
not exists(PhiInputOperand operand |
operand = instr.getAnOperand() and
operand.getPredecessorBlock() = pred
)
}
query predicate missingOperandType(Operand operand, string message) {
exists(Language::Function func, Instruction use |
not exists(operand.getType()) and
use = operand.getUse() and
func = use.getEnclosingFunction() and
message =
"Operand '" + operand.toString() + "' of instruction '" + use.getOpcode().toString() +
"' missing type in function '" + Language::getIdentityString(func) + "'."
)
}
query predicate duplicateChiOperand(
ChiInstruction chi, string message, IRFunction func, string funcText
) {
chi.getTotal() = chi.getPartial() and
message =
"Chi instruction for " + chi.getPartial().toString() +
" has duplicate operands in function $@" and
func = chi.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
}
query predicate sideEffectWithoutPrimary(
SideEffectInstruction instr, string message, IRFunction func, string funcText
) {
not exists(instr.getPrimaryInstruction()) and
message = "Side effect instruction missing primary instruction in function $@" and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
}
/**
* Holds if an instruction, other than `ExitFunction`, has no successors.
*/
query predicate instructionWithoutSuccessor(Instruction instr) {
not exists(instr.getASuccessor()) and
not instr instanceof ExitFunctionInstruction and
// Phi instructions aren't linked into the instruction-level flow graph.
not instr instanceof PhiInstruction and
not instr instanceof UnreachedInstruction
}
/**
* Holds if there are multiple (`n`) edges of kind `kind` from `source`,
* where `target` is among the targets of those edges.
*/
query predicate ambiguousSuccessors(Instruction source, EdgeKind kind, int n, Instruction target) {
n = strictcount(Instruction t | source.getSuccessor(kind) = t) and
n > 1 and
source.getSuccessor(kind) = target
}
/**
* Holds if `instr` in `f` is part of a loop even though the AST of `f`
* contains no element that can cause loops.
*/
query predicate unexplainedLoop(Language::Function f, Instruction instr) {
exists(IRBlock block |
instr.getBlock() = block and
block.getEnclosingFunction() = f and
block.getASuccessor+() = block
) and
not Language::hasPotentialLoop(f)
}
/**
* Holds if a `Phi` instruction is present in a block with fewer than two
* predecessors.
*/
query predicate unnecessaryPhiInstruction(PhiInstruction instr) {
count(instr.getBlock().getAPredecessor()) < 2
}
/**
* Holds if a memory operand is connected to a definition with an unmodeled result, other than
* `UnmodeledDefinition` itself.
*/
query predicate memoryOperandDefinitionIsUnmodeled(
Instruction instr, string message, IRFunction func, string funcText
) {
exists(MemoryOperand operand, Instruction def |
operand = instr.getAnOperand() and
not operand instanceof UnmodeledUseOperand and
def = operand.getAnyDef() and
not def.isResultModeled() and
not def instanceof UnmodeledDefinitionInstruction and
message =
"Memory operand definition has unmodeled result, but is not the `UnmodeledDefinition` instruction in function '$@'" and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
}
/**
* Holds if operand `operand` consumes a value that was defined in
* a different function.
*/
query predicate operandAcrossFunctions(Operand operand, Instruction instr, Instruction defInstr) {
operand.getUse() = instr and
operand.getAnyDef() = defInstr and
instr.getEnclosingIRFunction() != defInstr.getEnclosingIRFunction()
}
/**
* Holds if instruction `instr` is not in exactly one block.
*/
query predicate instructionWithoutUniqueBlock(Instruction instr, int blockCount) {
blockCount = count(instr.getBlock()) and
blockCount != 1
}
private predicate forwardEdge(IRBlock b1, IRBlock b2) {
b1.getASuccessor() = b2 and
not b1.getBackEdgeSuccessor(_) = b2
}
/**
* Holds if `f` contains a loop in which no edge is a back edge.
*
* This check ensures we don't have too _few_ back edges.
*/
query predicate containsLoopOfForwardEdges(IRFunction f) {
exists(IRBlock block |
forwardEdge+(block, block) and
block.getEnclosingIRFunction() = f
)
}
/**
* Holds if `block` is reachable from its function entry point but would not
* be reachable by traversing only forward edges. This check is skipped for
* functions containing `goto` statements as the property does not generally
* hold there.
*
* This check ensures we don't have too _many_ back edges.
*/
query predicate lostReachability(IRBlock block) {
exists(IRFunction f, IRBlock entry |
entry = f.getEntryBlock() and
entry.getASuccessor+() = block and
not forwardEdge+(entry, block) and
not Language::hasGoto(f.getFunction())
)
}
/**
* Holds if the number of back edges differs between the `Instruction` graph
* and the `IRBlock` graph.
*/
query predicate backEdgeCountMismatch(Language::Function f, int fromInstr, int fromBlock) {
fromInstr =
count(Instruction i1, Instruction i2 |
i1.getEnclosingFunction() = f and i1.getBackEdgeSuccessor(_) = i2
) and
fromBlock =
count(IRBlock b1, IRBlock b2 |
b1.getEnclosingFunction() = f and b1.getBackEdgeSuccessor(_) = b2
) and
fromInstr != fromBlock
}
/**
* Gets the point in the function at which the specified operand is evaluated. For most operands,
* this is at the instruction that consumes the use. For a `PhiInputOperand`, the effective point
* of evaluation is at the end of the corresponding predecessor block.
*/
private predicate pointOfEvaluation(Operand operand, IRBlock block, int index) {
block = operand.(PhiInputOperand).getPredecessorBlock() and
index = block.getInstructionCount()
or
exists(Instruction use |
use = operand.(NonPhiOperand).getUse() and
block.getInstruction(index) = use
)
}
/**
* Holds if `useOperand` has a definition that does not dominate the use.
*/
query predicate useNotDominatedByDefinition(
Operand useOperand, string message, IRFunction func, string funcText
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
defInstr instanceof PhiInstruction and
defBlock = defInstr.getBlock() and
defIndex = -1
or
defBlock.getInstruction(defIndex) = defInstr
) and
not (
defBlock.strictlyDominates(useBlock)
or
defBlock = useBlock and
defIndex < useIndex
) and
message =
"Operand '" + useOperand.toString() +
"' is not dominated by its definition in function '$@'." and
func = useOperand.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
}
query predicate switchInstructionWithoutDefaultEdge(
SwitchInstruction switchInstr, string message, IRFunction func, string funcText
) {
not exists(switchInstr.getDefaultSuccessor()) and
message =
"SwitchInstruction " + switchInstr.toString() + " without a DefaultEdge in function '$@'." and
func = switchInstr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
}
/**
* Holds if `instr` is on the chain of chi/phi instructions for all aliased
* memory.
*/
private predicate isOnAliasedDefinitionChain(Instruction instr) {
instr instanceof AliasedDefinitionInstruction
or
isOnAliasedDefinitionChain(instr.(ChiInstruction).getTotal())
or
isOnAliasedDefinitionChain(instr.(PhiInstruction).getAnInputOperand().getAnyDef())
}
private predicate shouldBeConflated(Instruction instr) {
isOnAliasedDefinitionChain(instr)
or
instr instanceof UnmodeledDefinitionInstruction
or
instr.getOpcode() instanceof Opcode::InitializeNonLocal
}
query predicate notMarkedAsConflated(Instruction instr) {
shouldBeConflated(instr) and
not instr.isResultConflated()
}
query predicate wronglyMarkedAsConflated(Instruction instr) {
instr.isResultConflated() and
not shouldBeConflated(instr)
}
query predicate invalidOverlap(
MemoryOperand useOperand, string message, IRFunction func, string funcText
) {
exists(Overlap overlap |
overlap = useOperand.getDefinitionOverlap() and
overlap instanceof MayPartiallyOverlap and
message =
"MemoryOperand '" + useOperand.toString() + "' has a `getDefinitionOverlap()` of '" +
overlap.toString() + "'." and
func = useOperand.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
}
}

Просмотреть файл

@ -1,8 +0,0 @@
/**
* @name SSA IR Sanity Check
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
* @kind table
* @id cpp/ssa-ir-sanity-check
*/
import IRSanity

Просмотреть файл

@ -1,340 +0,0 @@
private import IR
import InstructionSanity // module is below
import IRTypeSanity // module is in IRType.qll
module InstructionSanity {
private import internal.InstructionImports as Imports
private import Imports::OperandTag
private import Imports::Overlap
private import internal.IRInternal
/**
* Holds if instruction `instr` is missing an expected operand with tag `tag`.
*/
query predicate missingOperand(Instruction instr, string message, IRFunction func, string funcText) {
exists(OperandTag tag |
instr.getOpcode().hasOperand(tag) and
not exists(NonPhiOperand operand |
operand = instr.getAnOperand() and
operand.getOperandTag() = tag
) and
message =
"Instruction '" + instr.getOpcode().toString() +
"' is missing an expected operand with tag '" + tag.toString() + "' in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
}
/**
* Holds if instruction `instr` has an unexpected operand with tag `tag`.
*/
query predicate unexpectedOperand(Instruction instr, OperandTag tag) {
exists(NonPhiOperand operand |
operand = instr.getAnOperand() and
operand.getOperandTag() = tag
) and
not instr.getOpcode().hasOperand(tag) and
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
not (
instr instanceof BuiltInOperationInstruction and tag instanceof PositionalArgumentOperandTag
) and
not (instr instanceof InlineAsmInstruction and tag instanceof AsmOperandTag)
}
/**
* Holds if instruction `instr` has multiple operands with tag `tag`.
*/
query predicate duplicateOperand(
Instruction instr, string message, IRFunction func, string funcText
) {
exists(OperandTag tag, int operandCount |
operandCount =
strictcount(NonPhiOperand operand |
operand = instr.getAnOperand() and
operand.getOperandTag() = tag
) and
operandCount > 1 and
not tag instanceof UnmodeledUseOperandTag and
message =
"Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
" in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
}
/**
* Holds if `Phi` instruction `instr` is missing an operand corresponding to
* the predecessor block `pred`.
*/
query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
pred = instr.getBlock().getAPredecessor() and
not exists(PhiInputOperand operand |
operand = instr.getAnOperand() and
operand.getPredecessorBlock() = pred
)
}
query predicate missingOperandType(Operand operand, string message) {
exists(Language::Function func, Instruction use |
not exists(operand.getType()) and
use = operand.getUse() and
func = use.getEnclosingFunction() and
message =
"Operand '" + operand.toString() + "' of instruction '" + use.getOpcode().toString() +
"' missing type in function '" + Language::getIdentityString(func) + "'."
)
}
query predicate duplicateChiOperand(
ChiInstruction chi, string message, IRFunction func, string funcText
) {
chi.getTotal() = chi.getPartial() and
message =
"Chi instruction for " + chi.getPartial().toString() +
" has duplicate operands in function $@" and
func = chi.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
}
query predicate sideEffectWithoutPrimary(
SideEffectInstruction instr, string message, IRFunction func, string funcText
) {
not exists(instr.getPrimaryInstruction()) and
message = "Side effect instruction missing primary instruction in function $@" and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
}
/**
* Holds if an instruction, other than `ExitFunction`, has no successors.
*/
query predicate instructionWithoutSuccessor(Instruction instr) {
not exists(instr.getASuccessor()) and
not instr instanceof ExitFunctionInstruction and
// Phi instructions aren't linked into the instruction-level flow graph.
not instr instanceof PhiInstruction and
not instr instanceof UnreachedInstruction
}
/**
* Holds if there are multiple (`n`) edges of kind `kind` from `source`,
* where `target` is among the targets of those edges.
*/
query predicate ambiguousSuccessors(Instruction source, EdgeKind kind, int n, Instruction target) {
n = strictcount(Instruction t | source.getSuccessor(kind) = t) and
n > 1 and
source.getSuccessor(kind) = target
}
/**
* Holds if `instr` in `f` is part of a loop even though the AST of `f`
* contains no element that can cause loops.
*/
query predicate unexplainedLoop(Language::Function f, Instruction instr) {
exists(IRBlock block |
instr.getBlock() = block and
block.getEnclosingFunction() = f and
block.getASuccessor+() = block
) and
not Language::hasPotentialLoop(f)
}
/**
* Holds if a `Phi` instruction is present in a block with fewer than two
* predecessors.
*/
query predicate unnecessaryPhiInstruction(PhiInstruction instr) {
count(instr.getBlock().getAPredecessor()) < 2
}
/**
* Holds if a memory operand is connected to a definition with an unmodeled result, other than
* `UnmodeledDefinition` itself.
*/
query predicate memoryOperandDefinitionIsUnmodeled(
Instruction instr, string message, IRFunction func, string funcText
) {
exists(MemoryOperand operand, Instruction def |
operand = instr.getAnOperand() and
not operand instanceof UnmodeledUseOperand and
def = operand.getAnyDef() and
not def.isResultModeled() and
not def instanceof UnmodeledDefinitionInstruction and
message =
"Memory operand definition has unmodeled result, but is not the `UnmodeledDefinition` instruction in function '$@'" and
func = instr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
}
/**
* Holds if operand `operand` consumes a value that was defined in
* a different function.
*/
query predicate operandAcrossFunctions(Operand operand, Instruction instr, Instruction defInstr) {
operand.getUse() = instr and
operand.getAnyDef() = defInstr and
instr.getEnclosingIRFunction() != defInstr.getEnclosingIRFunction()
}
/**
* Holds if instruction `instr` is not in exactly one block.
*/
query predicate instructionWithoutUniqueBlock(Instruction instr, int blockCount) {
blockCount = count(instr.getBlock()) and
blockCount != 1
}
private predicate forwardEdge(IRBlock b1, IRBlock b2) {
b1.getASuccessor() = b2 and
not b1.getBackEdgeSuccessor(_) = b2
}
/**
* Holds if `f` contains a loop in which no edge is a back edge.
*
* This check ensures we don't have too _few_ back edges.
*/
query predicate containsLoopOfForwardEdges(IRFunction f) {
exists(IRBlock block |
forwardEdge+(block, block) and
block.getEnclosingIRFunction() = f
)
}
/**
* Holds if `block` is reachable from its function entry point but would not
* be reachable by traversing only forward edges. This check is skipped for
* functions containing `goto` statements as the property does not generally
* hold there.
*
* This check ensures we don't have too _many_ back edges.
*/
query predicate lostReachability(IRBlock block) {
exists(IRFunction f, IRBlock entry |
entry = f.getEntryBlock() and
entry.getASuccessor+() = block and
not forwardEdge+(entry, block) and
not Language::hasGoto(f.getFunction())
)
}
/**
* Holds if the number of back edges differs between the `Instruction` graph
* and the `IRBlock` graph.
*/
query predicate backEdgeCountMismatch(Language::Function f, int fromInstr, int fromBlock) {
fromInstr =
count(Instruction i1, Instruction i2 |
i1.getEnclosingFunction() = f and i1.getBackEdgeSuccessor(_) = i2
) and
fromBlock =
count(IRBlock b1, IRBlock b2 |
b1.getEnclosingFunction() = f and b1.getBackEdgeSuccessor(_) = b2
) and
fromInstr != fromBlock
}
/**
* Gets the point in the function at which the specified operand is evaluated. For most operands,
* this is at the instruction that consumes the use. For a `PhiInputOperand`, the effective point
* of evaluation is at the end of the corresponding predecessor block.
*/
private predicate pointOfEvaluation(Operand operand, IRBlock block, int index) {
block = operand.(PhiInputOperand).getPredecessorBlock() and
index = block.getInstructionCount()
or
exists(Instruction use |
use = operand.(NonPhiOperand).getUse() and
block.getInstruction(index) = use
)
}
/**
* Holds if `useOperand` has a definition that does not dominate the use.
*/
query predicate useNotDominatedByDefinition(
Operand useOperand, string message, IRFunction func, string funcText
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
defInstr instanceof PhiInstruction and
defBlock = defInstr.getBlock() and
defIndex = -1
or
defBlock.getInstruction(defIndex) = defInstr
) and
not (
defBlock.strictlyDominates(useBlock)
or
defBlock = useBlock and
defIndex < useIndex
) and
message =
"Operand '" + useOperand.toString() +
"' is not dominated by its definition in function '$@'." and
func = useOperand.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
}
query predicate switchInstructionWithoutDefaultEdge(
SwitchInstruction switchInstr, string message, IRFunction func, string funcText
) {
not exists(switchInstr.getDefaultSuccessor()) and
message =
"SwitchInstruction " + switchInstr.toString() + " without a DefaultEdge in function '$@'." and
func = switchInstr.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
}
/**
* Holds if `instr` is on the chain of chi/phi instructions for all aliased
* memory.
*/
private predicate isOnAliasedDefinitionChain(Instruction instr) {
instr instanceof AliasedDefinitionInstruction
or
isOnAliasedDefinitionChain(instr.(ChiInstruction).getTotal())
or
isOnAliasedDefinitionChain(instr.(PhiInstruction).getAnInputOperand().getAnyDef())
}
private predicate shouldBeConflated(Instruction instr) {
isOnAliasedDefinitionChain(instr)
or
instr instanceof UnmodeledDefinitionInstruction
or
instr.getOpcode() instanceof Opcode::InitializeNonLocal
}
query predicate notMarkedAsConflated(Instruction instr) {
shouldBeConflated(instr) and
not instr.isResultConflated()
}
query predicate wronglyMarkedAsConflated(Instruction instr) {
instr.isResultConflated() and
not shouldBeConflated(instr)
}
query predicate invalidOverlap(
MemoryOperand useOperand, string message, IRFunction func, string funcText
) {
exists(Overlap overlap |
overlap = useOperand.getDefinitionOverlap() and
overlap instanceof MayPartiallyOverlap and
message =
"MemoryOperand '" + useOperand.toString() + "' has a `getDefinitionOverlap()` of '" +
overlap.toString() + "'." and
func = useOperand.getEnclosingIRFunction() and
funcText = Language::getIdentityString(func.getFunction())
)
}
}

Просмотреть файл

@ -0,0 +1,8 @@
/**
* @name Unaliased SSA Consistency Check
* @description Performs consistency checks on the SSA construction. This query should have no results.
* @kind table
* @id csharp/unaliased-ssa-consistency-check
*/
import SSAConsistency

Просмотреть файл

@ -1,2 +1,2 @@
private import SSAConstruction as SSA
import SSA::SSASanity
import SSA::SSAConsistency

Просмотреть файл

@ -941,7 +941,7 @@ private module CachedForDebugging {
}
}
module SSASanity {
module SSAConsistency {
query predicate multipleOperandMemoryLocations(
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
) {

Просмотреть файл

@ -1,8 +0,0 @@
/**
* @name Unaliased SSA Sanity Check
* @description Performs sanity checks on the SSA construction. This query should have no results.
* @kind table
* @id csharp/unaliased-ssa-sanity-check
*/
import SSASanity

Просмотреть файл

@ -368,7 +368,7 @@ CSharpPRValueType getCanonicalOpaqueType(Type tag, int byteSize) {
getTypeSize(tag) = byteSize
}
module LanguageTypeSanity {
module LanguageTypeConsistency {
// Nothing interesting here for C# yet, but the module still has to exist because it is imported
// by `IRTypeSanity`.
// by `IRTypeConsistency`.
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше