mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
Added C# implementation
This commit is contained in:
@@ -3,4 +3,4 @@
|
||||
* publicly as the "IR".
|
||||
*/
|
||||
|
||||
import implementation.raw.IR
|
||||
import implementation.unaliased_ssa.IR
|
||||
|
||||
@@ -15,5 +15,7 @@ class IRConfiguration extends TIRConfiguration {
|
||||
/**
|
||||
* Holds if IR should be created for callable `callable`. By default, holds for all callables.
|
||||
*/
|
||||
predicate shouldCreateIRForFunction(Callable callable) { any() }
|
||||
predicate shouldCreateIRForFunction(Callable callable) {
|
||||
callable.getLocation().getFile().getExtension() = "cs"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
* @kind graph
|
||||
*/
|
||||
|
||||
import implementation.raw.PrintIR
|
||||
import implementation.unaliased_ssa.PrintIR
|
||||
|
||||
@@ -1 +1 @@
|
||||
import implementation.raw.PrintIR
|
||||
import implementation.unaliased_ssa.PrintIR
|
||||
|
||||
@@ -1 +1 @@
|
||||
import implementation.raw.gvn.ValueNumbering
|
||||
import implementation.unaliased_ssa.gvn.ValueNumbering
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
private import internal.ConstantAnalysisInternal
|
||||
private import semmle.code.cpp.ir.internal.IntegerPartial
|
||||
private import semmle.code.csharp.ir.internal.IntegerPartial
|
||||
private import IR
|
||||
|
||||
language[monotonicAggregates]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
private import internal.ConstantAnalysisInternal
|
||||
private import semmle.code.cpp.ir.internal.IntegerConstant
|
||||
private import semmle.code.csharp.ir.internal.IntegerConstant
|
||||
private import ConstantAnalysis
|
||||
import IR
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as IR
|
||||
import semmle.code.csharp.ir.implementation.unaliased_ssa.IR as IR
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
private import internal.ValueNumberingInternal
|
||||
private import cpp
|
||||
private import csharp
|
||||
private import IR
|
||||
|
||||
/**
|
||||
|
||||
@@ -1 +1 @@
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as IR
|
||||
import semmle.code.csharp.ir.implementation.unaliased_ssa.IR as IR
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
private import AliasAnalysisInternal
|
||||
private import cpp
|
||||
private import csharp
|
||||
private import InputIR
|
||||
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
|
||||
private import semmle.code.cpp.models.interfaces.Alias
|
||||
private import semmle.code.csharp.ir.internal.IntegerConstant as Ints
|
||||
|
||||
private class IntValue = Ints::IntValue;
|
||||
|
||||
@@ -26,17 +25,16 @@ string getBitOffsetString(IntValue bitOffset) {
|
||||
else result = "+?"
|
||||
}
|
||||
|
||||
///**
|
||||
// * Gets the offset of field `field` in bits.
|
||||
// */
|
||||
//private IntValue getFieldBitOffset(Field field) {
|
||||
// if field instanceof BitField
|
||||
// then result = Ints::add(Ints::mul(field.getByteOffset(), 8), field.(BitField).getBitOffset())
|
||||
// else result = Ints::mul(field.getByteOffset(), 8)
|
||||
//}
|
||||
/**
|
||||
* Gets the offset of field `field` in bits.
|
||||
*/
|
||||
private IntValue getFieldBitOffset(Field field) {
|
||||
if field instanceof BitField
|
||||
then result = Ints::add(Ints::mul(field.getByteOffset(), 8), field.(BitField).getBitOffset())
|
||||
else result = Ints::mul(field.getByteOffset(), 8)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the operand `tag` of instruction `instr` is used in a way that does
|
||||
* Holds if the operand `operand` of instruction `instr` is used in a way that does
|
||||
* not result in any address held in that operand from escaping beyond the
|
||||
* instruction.
|
||||
*/
|
||||
@@ -53,21 +51,18 @@ private predicate operandIsConsumedWithoutEscaping(Operand operand) {
|
||||
or
|
||||
// Neither operand of a PointerDiff escapes.
|
||||
instr instanceof PointerDiffInstruction
|
||||
or
|
||||
// Converting an address to a `bool` does not escape the address.
|
||||
instr.(ConvertInstruction).getResultType() instanceof BoolType
|
||||
)
|
||||
)
|
||||
or
|
||||
// Some standard function arguments never escape
|
||||
isNeverEscapesArgument(operand)
|
||||
// or
|
||||
// // Some standard function arguments never escape
|
||||
// isNeverEscapesArgument(operand)
|
||||
}
|
||||
|
||||
private predicate operandEscapesDomain(Operand operand) {
|
||||
not operandIsConsumedWithoutEscaping(operand) and
|
||||
not operandIsPropagated(operand, _) and
|
||||
not isArgumentForParameter(_, operand, _) and
|
||||
not isOnlyEscapesViaReturnArgument(operand) and
|
||||
// not isOnlyEscapesViaReturnArgument(operand) and
|
||||
not operand.getUse() instanceof ReturnValueInstruction and
|
||||
not operand instanceof PhiInputOperand
|
||||
}
|
||||
@@ -99,7 +94,7 @@ IntValue getPointerBitOffset(PointerOffsetInstruction instr) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if any address held in operand `tag` of instruction `instr` is
|
||||
* Holds if any address held in operand `operand` of instruction `instr` is
|
||||
* propagated to the result of `instr`, offset by the number of bits in
|
||||
* `bitOffset`. If the address is propagated, but the offset is not known to be
|
||||
* a constant, then `bitOffset` is unknown.
|
||||
@@ -108,29 +103,36 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
|
||||
exists(Instruction instr |
|
||||
instr = operand.getUse() and
|
||||
(
|
||||
// Converting to a non-virtual base class adds the offset of the base class.
|
||||
exists(ConvertToBaseInstruction convert |
|
||||
convert = instr and
|
||||
bitOffset = Ints::mul(convert.getDerivation().getByteOffset(), 8)
|
||||
)
|
||||
or
|
||||
// Converting to a derived class subtracts the offset of the base class.
|
||||
exists(ConvertToDerivedInstruction convert |
|
||||
convert = instr and
|
||||
bitOffset = Ints::neg(Ints::mul(convert.getDerivation().getByteOffset(), 8))
|
||||
)
|
||||
or
|
||||
// Converting to a virtual base class adds an unknown offset.
|
||||
instr instanceof ConvertToVirtualBaseInstruction and
|
||||
bitOffset = Ints::unknown()
|
||||
or
|
||||
// REVIEW: See the REVIEW comment bellow
|
||||
// // Converting to a non-virtual base class adds the offset of the base class.
|
||||
// exists(ConvertToBaseInstruction convert |
|
||||
// convert = instr and
|
||||
// bitOffset = Ints::mul(convert.getDerivation().getByteOffset(), 8)
|
||||
// )
|
||||
// or
|
||||
// // Converting to a derived class subtracts the offset of the base class.
|
||||
// exists(ConvertToDerivedInstruction convert |
|
||||
// convert = instr and
|
||||
// bitOffset = Ints::neg(Ints::mul(convert.getDerivation().getByteOffset(), 8))
|
||||
// )
|
||||
// or
|
||||
// // Converting to a virtual base class adds an unknown offset.
|
||||
// instr instanceof ConvertToVirtualBaseInstruction and
|
||||
// bitOffset = Ints::unknown()
|
||||
// or
|
||||
// REVIEW: In the C# IR, we should ignore the above types of conversion all together,
|
||||
// since first of all they do not provide correct information (nothing is known
|
||||
// for sure about heap allocated objects) and second of all even if we create a
|
||||
// virtual memory model for the IR I don't think such conversions provide any meaningful
|
||||
// information;
|
||||
// Conversion to another pointer type propagates the source address.
|
||||
// REVIEW: Is this needed?
|
||||
exists(ConvertInstruction convert, Type resultType |
|
||||
convert = instr and
|
||||
resultType = convert.getResultType() and
|
||||
(
|
||||
resultType instanceof PointerType or
|
||||
resultType instanceof Class //REVIEW: Remove when all glvalues are pointers
|
||||
resultType instanceof RefType
|
||||
) and
|
||||
bitOffset = 0
|
||||
)
|
||||
@@ -139,15 +141,15 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
|
||||
// the address with an offset.
|
||||
bitOffset = getPointerBitOffset(instr.(PointerOffsetInstruction))
|
||||
or
|
||||
// Computing a field address from a pointer propagates the address plus the
|
||||
// offset of the field.
|
||||
bitOffset = getFieldBitOffset(instr.(FieldAddressInstruction).getField())
|
||||
or
|
||||
// or
|
||||
// // Computing a field address from a pointer propagates the address plus the
|
||||
// // offset of the field.
|
||||
// bitOffset = getFieldBitOffset(instr.(FieldAddressInstruction).getField())
|
||||
// A copy propagates the source value.
|
||||
operand = instr.(CopyInstruction).getSourceValueOperand() and bitOffset = 0
|
||||
or
|
||||
// Some functions are known to propagate an argument
|
||||
isAlwaysReturnedArgument(operand) and bitOffset = 0
|
||||
// or
|
||||
// // Some functions are known to propagate an argument
|
||||
// isAlwaysReturnedArgument(operand) and bitOffset = 0
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -167,8 +169,8 @@ private predicate operandEscapesNonReturn(Operand operand) {
|
||||
)
|
||||
)
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and resultEscapesNonReturn(operand.getUse())
|
||||
or
|
||||
// or
|
||||
// isOnlyEscapesViaReturnArgument(operand) and resultEscapesNonReturn(operand.getUse())
|
||||
operand instanceof PhiInputOperand and
|
||||
resultEscapesNonReturn(operand.getUse())
|
||||
or
|
||||
@@ -190,8 +192,8 @@ private predicate operandMayReachReturn(Operand operand) {
|
||||
// The address is returned
|
||||
operand.getUse() instanceof ReturnValueInstruction
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and resultMayReachReturn(operand.getUse())
|
||||
or
|
||||
// or
|
||||
// isOnlyEscapesViaReturnArgument(operand) and resultMayReachReturn(operand.getUse())
|
||||
operand instanceof PhiInputOperand and
|
||||
resultMayReachReturn(operand.getUse())
|
||||
}
|
||||
@@ -216,49 +218,50 @@ private predicate operandReturned(Operand operand, IntValue bitOffset) {
|
||||
operand.getUse() instanceof ReturnValueInstruction and
|
||||
bitOffset = 0
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and
|
||||
// isOnlyEscapesViaReturnArgument(operand) and
|
||||
resultReturned(operand.getUse(), _) and
|
||||
bitOffset = Ints::unknown()
|
||||
}
|
||||
|
||||
private predicate isArgumentForParameter(CallInstruction ci, Operand operand, Instruction init) {
|
||||
exists(Function f |
|
||||
exists(Callable c |
|
||||
ci = operand.getUse() and
|
||||
f = ci.getStaticCallTarget() and
|
||||
c = ci.getStaticCallTarget() and
|
||||
(
|
||||
init.(InitializeParameterInstruction).getParameter() = f
|
||||
init.(InitializeParameterInstruction).getParameter() = c
|
||||
.getParameter(operand.(PositionalArgumentOperand).getIndex())
|
||||
or
|
||||
init instanceof InitializeThisInstruction and
|
||||
init.getEnclosingFunction() = f and
|
||||
init.getEnclosingFunction() = c and
|
||||
operand instanceof ThisArgumentOperand
|
||||
) and
|
||||
not f.isVirtual() and
|
||||
not f instanceof AliasFunction
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isAlwaysReturnedArgument(Operand operand) {
|
||||
exists(AliasFunction f |
|
||||
f = operand.getUse().(CallInstruction).getStaticCallTarget() and
|
||||
f.parameterIsAlwaysReturned(operand.(PositionalArgumentOperand).getIndex())
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isOnlyEscapesViaReturnArgument(Operand operand) {
|
||||
exists(AliasFunction f |
|
||||
f = operand.getUse().(CallInstruction).getStaticCallTarget() and
|
||||
f.parameterEscapesOnlyViaReturn(operand.(PositionalArgumentOperand).getIndex())
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isNeverEscapesArgument(Operand operand) {
|
||||
exists(AliasFunction f |
|
||||
f = operand.getUse().(CallInstruction).getStaticCallTarget() and
|
||||
f.parameterNeverEscapes(operand.(PositionalArgumentOperand).getIndex())
|
||||
) // and
|
||||
// not f.isVirtual() and
|
||||
// not f instanceof AliasFunction
|
||||
)
|
||||
}
|
||||
|
||||
// REVIEW: Those three predicates are used to model the behaviour of C++ library functions
|
||||
// for which the code was not accessible, so we should ignore them
|
||||
//private predicate isAlwaysReturnedArgument(Operand operand) {
|
||||
// exists(AliasFunction f |
|
||||
// f = operand.getUse().(CallInstruction).getStaticCallTarget() and
|
||||
// f.parameterIsAlwaysReturned(operand.(PositionalArgumentOperand).getIndex())
|
||||
// )
|
||||
//}
|
||||
//
|
||||
//private predicate isOnlyEscapesViaReturnArgument(Operand operand) {
|
||||
// exists(AliasFunction f |
|
||||
// f = operand.getUse().(CallInstruction).getStaticCallTarget() and
|
||||
// f.parameterEscapesOnlyViaReturn(operand.(PositionalArgumentOperand).getIndex())
|
||||
// )
|
||||
//}
|
||||
//
|
||||
//private predicate isNeverEscapesArgument(Operand operand) {
|
||||
// exists(AliasFunction f |
|
||||
// f = operand.getUse().(CallInstruction).getStaticCallTarget() and
|
||||
// f.parameterNeverEscapes(operand.(PositionalArgumentOperand).getIndex())
|
||||
// )
|
||||
//}
|
||||
private predicate resultReturned(Instruction instr, IntValue bitOffset) {
|
||||
operandReturned(instr.getAUse(), bitOffset)
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
import semmle.code.cpp.ir.implementation.raw.IR as InputIR
|
||||
import semmle.code.csharp.ir.implementation.raw.IR as InputIR
|
||||
|
||||
@@ -1 +1 @@
|
||||
import semmle.code.cpp.ir.implementation.EdgeKind as EdgeKind
|
||||
import semmle.code.csharp.ir.implementation.EdgeKind as EdgeKind
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
import semmle.code.cpp.ir.implementation.EdgeKind as EdgeKind
|
||||
import semmle.code.cpp.ir.implementation.MemoryAccessKind as MemoryAccessKind
|
||||
import semmle.code.csharp.ir.implementation.EdgeKind as EdgeKind
|
||||
import semmle.code.csharp.ir.implementation.MemoryAccessKind as MemoryAccessKind
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
|
||||
import SSAConstruction as Construction
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import semmle.code.cpp.ir.implementation.TempVariableTag as TempVariableTag
|
||||
import semmle.code.cpp.ir.internal.IRUtilities as IRUtilities
|
||||
import semmle.code.cpp.ir.internal.TempVariableTag as TTempVariableTag
|
||||
import semmle.code.cpp.ir.implementation.internal.TIRVariable as TIRVariable
|
||||
import semmle.code.csharp.ir.implementation.TempVariableTag as TempVariableTag
|
||||
import semmle.code.csharp.ir.internal.IRUtilities as IRUtilities
|
||||
import semmle.code.csharp.ir.internal.TempVariableTag as TTempVariableTag
|
||||
import semmle.code.csharp.ir.implementation.internal.TIRVariable as TIRVariable
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import semmle.code.cpp.ir.implementation.EdgeKind as EdgeKind
|
||||
import semmle.code.cpp.ir.implementation.MemoryAccessKind as MemoryAccessKind
|
||||
import semmle.code.cpp.ir.implementation.Opcode as Opcode
|
||||
import semmle.code.cpp.ir.implementation.internal.OperandTag as OperandTag
|
||||
import semmle.code.csharp.ir.implementation.EdgeKind as EdgeKind
|
||||
import semmle.code.csharp.ir.implementation.MemoryAccessKind as MemoryAccessKind
|
||||
import semmle.code.csharp.ir.implementation.Opcode as Opcode
|
||||
import semmle.code.csharp.ir.implementation.internal.OperandTag as OperandTag
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import semmle.code.cpp.ir.implementation.MemoryAccessKind as MemoryAccessKind
|
||||
import semmle.code.cpp.ir.internal.Overlap as Overlap
|
||||
import semmle.code.cpp.ir.implementation.internal.OperandTag as OperandTag
|
||||
import semmle.code.csharp.ir.implementation.MemoryAccessKind as MemoryAccessKind
|
||||
import semmle.code.csharp.ir.internal.Overlap as Overlap
|
||||
import semmle.code.csharp.ir.implementation.internal.OperandTag as OperandTag
|
||||
|
||||
@@ -1 +1 @@
|
||||
import semmle.code.cpp.ir.IRConfiguration as IRConfiguration
|
||||
import semmle.code.csharp.ir.IRConfiguration as IRConfiguration
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import SSAConstructionInternal
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.implementation.Opcode
|
||||
private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
||||
private import semmle.code.cpp.ir.internal.Overlap
|
||||
private import semmle.code.csharp.ir.implementation.Opcode
|
||||
private import semmle.code.csharp.ir.implementation.internal.OperandTag
|
||||
private import semmle.code.csharp.ir.internal.Overlap
|
||||
private import NewIR
|
||||
private import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
|
||||
|
||||
private class OldBlock = Reachability::ReachableBlock;
|
||||
|
||||
@@ -18,7 +18,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate functionHasIR(Function func) {
|
||||
predicate functionHasIR(Language::Function func) {
|
||||
exists(OldIR::IRFunction irFunc | irFunc.getFunction() = func)
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ private module Cached {
|
||||
not oldInstruction instanceof OldIR::PhiInstruction and
|
||||
hasChiNode(_, oldInstruction)
|
||||
} or
|
||||
Unreached(Function function) {
|
||||
Unreached(Language::Function function) {
|
||||
exists(OldInstruction oldInstruction |
|
||||
function = oldInstruction.getEnclosingFunction() and
|
||||
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
|
||||
@@ -50,7 +50,9 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag, Type type) {
|
||||
predicate hasTempVariable(
|
||||
Language::Function func, Language::AST ast, TempVariableTag tag, Language::Type type
|
||||
) {
|
||||
exists(OldIR::IRTempVariable var |
|
||||
var.getEnclosingFunction() = func and
|
||||
var.getAST() = ast and
|
||||
@@ -135,7 +137,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
Type getInstructionOperandType(Instruction instr, TypedOperandTag tag) {
|
||||
Language::Type getInstructionOperandType(Instruction instr, TypedOperandTag tag) {
|
||||
exists(OldInstruction oldInstruction, OldIR::TypedOperand oldOperand |
|
||||
oldInstruction = getOldInstruction(instr) and
|
||||
oldOperand = oldInstruction.getAnOperand() and
|
||||
@@ -151,7 +153,7 @@ private module Cached {
|
||||
oldOperand = oldInstruction.getAnOperand() and
|
||||
tag = oldOperand.getOperandTag() and
|
||||
// Only return a result for operands that need an explicit result size.
|
||||
oldOperand.getType() instanceof UnknownType and
|
||||
oldOperand.getType() instanceof Language::UnknownType and
|
||||
result = oldOperand.getSize()
|
||||
)
|
||||
}
|
||||
@@ -196,20 +198,21 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
Expr getInstructionConvertedResultExpression(Instruction instruction) {
|
||||
Language::Expr getInstructionConvertedResultExpression(Instruction instruction) {
|
||||
result = getOldInstruction(instruction).getConvertedResultExpression()
|
||||
}
|
||||
|
||||
cached
|
||||
Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
|
||||
Language::Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
|
||||
result = getOldInstruction(instruction).getUnconvertedResultExpression()
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* This adds Chi nodes to the instruction successor relation; if an instruction has a Chi node,
|
||||
* that node is its successor in the new successor relation, and the Chi node's successors are
|
||||
* the new instructions generated from the successors of the old instruction
|
||||
*/
|
||||
|
||||
cached
|
||||
Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
|
||||
if hasChiNode(_, getOldInstruction(instruction))
|
||||
@@ -252,7 +255,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
Locatable getInstructionAST(Instruction instruction) {
|
||||
Language::AST getInstructionAST(Instruction instruction) {
|
||||
exists(OldInstruction oldInstruction |
|
||||
instruction = WrappedInstruction(oldInstruction)
|
||||
or
|
||||
@@ -270,7 +273,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate instructionHasType(Instruction instruction, Type type, boolean isGLValue) {
|
||||
predicate instructionHasType(Instruction instruction, Language::Type type, boolean isGLValue) {
|
||||
exists(OldInstruction oldInstruction |
|
||||
instruction = WrappedInstruction(oldInstruction) and
|
||||
type = oldInstruction.getResultType() and
|
||||
@@ -291,7 +294,7 @@ private module Cached {
|
||||
)
|
||||
or
|
||||
instruction = Unreached(_) and
|
||||
type instanceof VoidType and
|
||||
type instanceof Language::VoidType and
|
||||
isGLValue = false
|
||||
}
|
||||
|
||||
@@ -338,12 +341,12 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
Field getInstructionField(Instruction instruction) {
|
||||
Language::Field getInstructionField(Instruction instruction) {
|
||||
result = getOldInstruction(instruction).(OldIR::FieldInstruction).getField()
|
||||
}
|
||||
|
||||
cached
|
||||
Function getInstructionFunction(Instruction instruction) {
|
||||
Language::Function getInstructionFunction(Instruction instruction) {
|
||||
result = getOldInstruction(instruction).(OldIR::FunctionInstruction).getFunctionSymbol()
|
||||
}
|
||||
|
||||
@@ -353,19 +356,19 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
StringLiteral getInstructionStringLiteral(Instruction instruction) {
|
||||
Language::StringLiteral getInstructionStringLiteral(Instruction instruction) {
|
||||
result = getOldInstruction(instruction).(OldIR::StringConstantInstruction).getValue()
|
||||
}
|
||||
|
||||
cached
|
||||
BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) {
|
||||
Language::BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) {
|
||||
result = getOldInstruction(instruction)
|
||||
.(OldIR::BuiltInOperationInstruction)
|
||||
.getBuiltInOperation()
|
||||
}
|
||||
|
||||
cached
|
||||
Type getInstructionExceptionType(Instruction instruction) {
|
||||
Language::Type getInstructionExceptionType(Instruction instruction) {
|
||||
result = getOldInstruction(instruction).(OldIR::CatchByTypeInstruction).getExceptionType()
|
||||
}
|
||||
|
||||
@@ -377,12 +380,14 @@ private module Cached {
|
||||
cached
|
||||
int getInstructionResultSize(Instruction instruction) {
|
||||
// Only return a result for instructions that needed an explicit result size.
|
||||
instruction.getResultType() instanceof UnknownType and
|
||||
instruction.getResultType() instanceof Language::UnknownType and
|
||||
result = getOldInstruction(instruction).getResultSize()
|
||||
}
|
||||
|
||||
cached
|
||||
predicate getInstructionInheritance(Instruction instruction, Class baseClass, Class derivedClass) {
|
||||
predicate getInstructionInheritance(
|
||||
Instruction instruction, Language::Class baseClass, Language::Class derivedClass
|
||||
) {
|
||||
exists(OldIR::InheritanceConversionInstruction oldInstr |
|
||||
oldInstr = getOldInstruction(instruction) and
|
||||
baseClass = oldInstr.getBaseClass() and
|
||||
@@ -834,7 +839,7 @@ module DefUse {
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose some of the internal predicates to PrintSSA.qll. We do this by publically importing those modules in the
|
||||
* Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the
|
||||
* `DebugSSA` module, which is then imported by PrintSSA.
|
||||
*/
|
||||
module DebugSSA {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import semmle.code.cpp.ir.implementation.raw.IR as OldIR
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.reachability.ReachableBlock as Reachability
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.reachability.Dominance as Dominance
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as NewIR
|
||||
import semmle.code.csharp.ir.implementation.raw.IR as OldIR
|
||||
import semmle.code.csharp.ir.implementation.raw.internal.reachability.ReachableBlock as Reachability
|
||||
import semmle.code.csharp.ir.implementation.raw.internal.reachability.Dominance as Dominance
|
||||
import semmle.code.csharp.ir.implementation.unaliased_ssa.IR as NewIR
|
||||
import SimpleSSA as Alias
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import AliasAnalysis
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.implementation.raw.IR
|
||||
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
|
||||
private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
||||
private import semmle.code.cpp.ir.internal.Overlap
|
||||
private import csharp
|
||||
private import semmle.code.csharp.ir.implementation.raw.IR
|
||||
private import semmle.code.csharp.ir.internal.IntegerConstant as Ints
|
||||
private import semmle.code.csharp.ir.implementation.internal.OperandTag
|
||||
private import semmle.code.csharp.ir.internal.Overlap
|
||||
|
||||
private class IntValue = Ints::IntValue;
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
missingOperand
|
||||
unexpectedOperand
|
||||
duplicateOperand
|
||||
missingPhiOperand
|
||||
missingOperandType
|
||||
instructionWithoutSuccessor
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
unnecessaryPhiInstruction
|
||||
operandAcrossFunctions
|
||||
instructionWithoutUniqueBlock
|
||||
containsLoopOfForwardEdges
|
||||
lostReachability
|
||||
backEdgeCountMismatch
|
||||
useNotDominatedByDefinition
|
||||
@@ -0,0 +1 @@
|
||||
semmle/code/csharp/ir/implementation/unaliased_ssa/IRSanity.ql
|
||||
Reference in New Issue
Block a user