зеркало из 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/raw/IR.qll",
|
||||||
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IR.qll"
|
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IR.qll"
|
||||||
],
|
],
|
||||||
"IR IRSanity": [
|
"IR IRConsistency": [
|
||||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRSanity.qll",
|
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRConsistency.qll",
|
||||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRSanity.qll",
|
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.qll",
|
||||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRSanity.qll",
|
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRConsistency.qll",
|
||||||
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRSanity.qll",
|
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRConsistency.qll",
|
||||||
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRSanity.qll"
|
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRConsistency.qll"
|
||||||
],
|
],
|
||||||
"IR PrintIR": [
|
"IR PrintIR": [
|
||||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll",
|
"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",
|
"cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll",
|
||||||
"csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll"
|
"csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll"
|
||||||
],
|
],
|
||||||
"IR SSASanity": [
|
"IR SSAConsistency": [
|
||||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll",
|
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll",
|
||||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.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/SSASanity.qll"
|
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll"
|
||||||
],
|
],
|
||||||
"C++ IR InstructionImports": [
|
"C++ IR InstructionImports": [
|
||||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionImports.qll",
|
"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.
|
* INTERNAL: Do not use.
|
||||||
* Query predicates used to check invariants that should hold for all `Cast`
|
* 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,
|
* nodes. To run all consistency queries for the ASTs, including the ones below,
|
||||||
* run "semmle/code/cpp/ASTSanity.ql".
|
* run "semmle/code/cpp/ASTConsistency.ql".
|
||||||
*/
|
*/
|
||||||
module CastSanity {
|
module CastConsistency {
|
||||||
query predicate multipleSemanticConversionStrings(Cast cast, Type fromType, string kind) {
|
query predicate multipleSemanticConversionStrings(Cast cast, Type fromType, string kind) {
|
||||||
// Every cast should have exactly one semantic conversion kind
|
// Every cast should have exactly one semantic conversion kind
|
||||||
count(cast.getSemanticConversionString()) > 1 and
|
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 }
|
final override int getByteSize() { result = byteSize }
|
||||||
}
|
}
|
||||||
|
|
||||||
module IRTypeSanity {
|
module IRTypeConsistency {
|
||||||
query predicate missingCanonicalLanguageType(IRType type, string message) {
|
query predicate missingCanonicalLanguageType(IRType type, string message) {
|
||||||
not exists(type.getCanonicalLanguageType()) and
|
not exists(type.getCanonicalLanguageType()) and
|
||||||
message = "Type does not have a canonical `LanguageType`"
|
message = "Type does not have a canonical `LanguageType`"
|
||||||
|
@ -300,5 +300,5 @@ module IRTypeSanity {
|
||||||
concat(type.getIRType().toString(), ", ")
|
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
|
private import IR
|
||||||
import InstructionSanity // module is below
|
import InstructionConsistency // module is below
|
||||||
import IRTypeSanity // module is in IRType.qll
|
import IRTypeConsistency // module is in IRType.qll
|
||||||
|
|
||||||
module InstructionSanity {
|
module InstructionConsistency {
|
||||||
private import internal.InstructionImports as Imports
|
private import internal.InstructionImports as Imports
|
||||||
private import Imports::OperandTag
|
private import Imports::OperandTag
|
||||||
private import Imports::Overlap
|
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
|
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(
|
query predicate multipleOperandMemoryLocations(
|
||||||
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
|
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
|
private import IR
|
||||||
import InstructionSanity // module is below
|
import InstructionConsistency // module is below
|
||||||
import IRTypeSanity // module is in IRType.qll
|
import IRTypeConsistency // module is in IRType.qll
|
||||||
|
|
||||||
module InstructionSanity {
|
module InstructionConsistency {
|
||||||
private import internal.InstructionImports as Imports
|
private import internal.InstructionImports as Imports
|
||||||
private import Imports::OperandTag
|
private import Imports::OperandTag
|
||||||
private import Imports::Overlap
|
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
|
private import IR
|
||||||
import InstructionSanity // module is below
|
import InstructionConsistency // module is below
|
||||||
import IRTypeSanity // module is in IRType.qll
|
import IRTypeConsistency // module is in IRType.qll
|
||||||
|
|
||||||
module InstructionSanity {
|
module InstructionConsistency {
|
||||||
private import internal.InstructionImports as Imports
|
private import internal.InstructionImports as Imports
|
||||||
private import Imports::OperandTag
|
private import Imports::OperandTag
|
||||||
private import Imports::Overlap
|
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
|
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(
|
query predicate multipleOperandMemoryLocations(
|
||||||
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
|
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)
|
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) {
|
query predicate missingCppType(Type type, string message) {
|
||||||
not exists(getTypeForPRValue(type)) and
|
not exists(getTypeForPRValue(type)) and
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
/**
|
/**
|
||||||
* @name Padding Sanity Check
|
* @name Padding Consistency Check
|
||||||
* @description Performs sanity checks for the padding library. This query should have no results.
|
* @description Performs consistency checks for the padding library. This query should have no results.
|
||||||
* @kind table
|
* @kind table
|
||||||
* @id cpp/padding-sanity-check
|
* @id cpp/padding-consistency-check
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Padding
|
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
|
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
|
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
|
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
|
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 }
|
final override int getByteSize() { result = byteSize }
|
||||||
}
|
}
|
||||||
|
|
||||||
module IRTypeSanity {
|
module IRTypeConsistency {
|
||||||
query predicate missingCanonicalLanguageType(IRType type, string message) {
|
query predicate missingCanonicalLanguageType(IRType type, string message) {
|
||||||
not exists(type.getCanonicalLanguageType()) and
|
not exists(type.getCanonicalLanguageType()) and
|
||||||
message = "Type does not have a canonical `LanguageType`"
|
message = "Type does not have a canonical `LanguageType`"
|
||||||
|
@ -300,5 +300,5 @@ module IRTypeSanity {
|
||||||
concat(type.getIRType().toString(), ", ")
|
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
|
private import IR
|
||||||
import InstructionSanity // module is below
|
import InstructionConsistency // module is below
|
||||||
import IRTypeSanity // module is in IRType.qll
|
import IRTypeConsistency // module is in IRType.qll
|
||||||
|
|
||||||
module InstructionSanity {
|
module InstructionConsistency {
|
||||||
private import internal.InstructionImports as Imports
|
private import internal.InstructionImports as Imports
|
||||||
private import Imports::OperandTag
|
private import Imports::OperandTag
|
||||||
private import Imports::Overlap
|
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
|
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(
|
query predicate multipleOperandMemoryLocations(
|
||||||
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
|
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
|
getTypeSize(tag) = byteSize
|
||||||
}
|
}
|
||||||
|
|
||||||
module LanguageTypeSanity {
|
module LanguageTypeConsistency {
|
||||||
// Nothing interesting here for C# yet, but the module still has to exist because it is imported
|
// Nothing interesting here for C# yet, but the module still has to exist because it is imported
|
||||||
// by `IRTypeSanity`.
|
// by `IRTypeConsistency`.
|
||||||
}
|
}
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче