зеркало из https://github.com/github/codeql.git
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:
Родитель
86a774d912
Коммит
09d1da2f7a
|
@ -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`.
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче