C++, C#: Share unaliased SSA files between languages

Most of the C# diffs are from bringing those files in sync with the latest C++ files.
This commit is contained in:
Dave Bartolomeo
2019-09-27 13:46:42 -07:00
parent 5585ccd509
commit f76334c24a
25 changed files with 226 additions and 165 deletions

View File

@@ -47,31 +47,36 @@
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll"
],
"IR IRBlock": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRBlock.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRBlock.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRBlock.qll"
],
"IR IRVariable": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll"
],
"IR IRFunction": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRFunction.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRFunction.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRFunction.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRFunction.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRFunction.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRFunction.qll"
],
"IR Operand": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Operand.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Operand.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Operand.qll"
],
"IR IRType": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll",
@@ -89,19 +94,22 @@
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IR.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IR.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll",
"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"
],
"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/raw/IRSanity.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRSanity.qll"
],
"IR PrintIR": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/PrintIR.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/PrintIR.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/PrintIR.qll"
],
"IR IntegerConstant": [
"cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll",
@@ -165,17 +173,27 @@
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintIRImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintIRImports.qll"
],
"C++ SSA SSAConstructionImports": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstructionImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstructionImports.qll"
],
"C++ SSA AliasAnalysis": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll"
],
"C++ SSA SSAConstruction": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll"
"IR SSA SimpleSSA": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll"
],
"C++ SSA PrintSSA": [
"IR SSA SSAConstruction": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll"
],
"IR SSA PrintSSA": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll"
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll"
],
"C++ IR ValueNumber": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll",
@@ -209,21 +227,27 @@
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/PrintDominance.qll"
],
"C# IR InstructionImports": [
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/InstructionImports.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/InstructionImports.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/InstructionImports.qll"
],
"C# IR IRImports": [
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRImports.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRImports.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/IRImports.qll"
],
"C# IR IRBlockImports": [
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRBlockImports.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRBlockImports.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll"
],
"C# IR IRVariableImports": [
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRVariableImports.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRVariableImports.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/IRVariableImports.qll"
],
"C# IR OperandImports": [
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/OperandImports.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/OperandImports.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/OperandImports.qll"
],
"C# IR PrintIRImports": [
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/PrintIRImports.qll"
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/PrintIRImports.qll",
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/PrintIRImports.qll"
]
}

View File

@@ -4,7 +4,7 @@
private import internal.IRTypeInternal
newtype TIRType =
private newtype TIRType =
TIRVoidType() or
TIRUnknownType() or
TIRErrorType() {

View File

@@ -1,7 +1,5 @@
import SSAConstructionInternal
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 SSAConstructionImports
private import NewIR
private class OldBlock = Reachability::ReachableBlock;

View File

@@ -0,0 +1,3 @@
import semmle.code.cpp.ir.implementation.Opcode
import semmle.code.cpp.ir.implementation.internal.OperandTag
import semmle.code.cpp.ir.internal.Overlap

View File

@@ -1,7 +1,5 @@
import SSAConstructionInternal
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 SSAConstructionImports
private import NewIR
private class OldBlock = Reachability::ReachableBlock;

View File

@@ -0,0 +1,3 @@
import semmle.code.cpp.ir.implementation.Opcode
import semmle.code.cpp.ir.implementation.internal.OperandTag
import semmle.code.cpp.ir.internal.Overlap

View File

@@ -1,9 +1,5 @@
import AliasAnalysis
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.IRCppLanguage as Language
private import semmle.code.cpp.ir.internal.Overlap
private import SimpleSSAImports
private class IntValue = Ints::IntValue;

View File

@@ -0,0 +1,5 @@
import semmle.code.cpp.ir.implementation.raw.IR
import semmle.code.cpp.ir.internal.IntegerConstant as Ints
import semmle.code.cpp.ir.implementation.internal.OperandTag
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
import semmle.code.cpp.ir.internal.Overlap

View File

@@ -1,4 +1,4 @@
import semmle.code.csharp.ir.implementation.IRType as IRType
import semmle.code.csharp.ir.implementation.MemoryAccessKind as MemoryAccessKind
import semmle.code.csharp.ir.implementation.IRType as IRType
import semmle.code.csharp.ir.internal.Overlap as Overlap
import semmle.code.csharp.ir.implementation.internal.OperandTag as OperandTag

View File

@@ -5,6 +5,7 @@ import IRVariable
import Operand
private import internal.IRImports as Imports
import Imports::EdgeKind
import Imports::IRType
import Imports::MemoryAccessKind
private newtype TIRPropertyProvider = MkIRPropertyProvider()

View File

@@ -1,2 +1,3 @@
private import IR
import InstructionSanity
import IRTypeSanity

View File

@@ -5,6 +5,7 @@ import Imports::TempVariableTag
private import Imports::IRUtilities
private import Imports::TTempVariableTag
private import Imports::TIRVariable
private import Imports::IRType
IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var) {
result.getVariable() = var and
@@ -24,7 +25,21 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the type of the variable.
*/
abstract Language::Type getType();
final Language::Type getType() {
getLanguageType().hasType(result, false)
}
/**
* Gets the language-neutral type of the variable.
*/
final IRType getIRType() {
result = getLanguageType().getIRType()
}
/**
* Gets the type of the variable.
*/
abstract Language::LanguageType getLanguageType();
/**
* Gets the AST node that declared this variable, or that introduced this
@@ -59,7 +74,7 @@ abstract class IRVariable extends TIRVariable {
*/
class IRUserVariable extends IRVariable, TIRUserVariable {
Language::Variable var;
Language::Type type;
Language::LanguageType type;
IRUserVariable() { this = TIRUserVariable(var, type, func) }
@@ -71,7 +86,7 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
result = getVariable().toString() + " " + getVariable().getLocation().toString()
}
final override Language::Type getType() { result = type }
final override Language::LanguageType getLanguageType() { result = type }
/**
* Gets the original user-declared variable.
@@ -110,11 +125,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
Language::AST ast;
TempVariableTag tag;
Language::Type type;
Language::LanguageType type;
IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) }
final override Language::Type getType() { result = type }
final override Language::LanguageType getLanguageType() { result = type }
final override Language::AST getAST() { result = ast }

View File

@@ -5,6 +5,7 @@ import IRVariable
import Operand
private import internal.InstructionImports as Imports
import Imports::EdgeKind
import Imports::IRType
import Imports::MemoryAccessKind
import Imports::Opcode
private import Imports::OperandTag
@@ -113,10 +114,13 @@ module InstructionSanity {
}
query predicate missingOperandType(Operand operand, string message) {
exists(Language::Function func |
exists(Language::Function func, Instruction use |
not exists(operand.getType()) and
func = operand.getUse().getEnclosingFunction() and
message = "Operand missing type in function '" + Language::getIdentityString(func) + "'."
use = operand.getUse() and
func = use.getEnclosingFunction() and
message = "Operand '" + operand.toString() + "' of instruction '" +
use.getOpcode().toString() + "' missing type in function '" +
Language::getIdentityString(func) + "'."
)
}
@@ -312,7 +316,7 @@ class Instruction extends Construction::TInstruction {
}
private string getResultPrefix() {
if getResultType() instanceof Language::VoidType
if getResultIRType() instanceof IRVoidType
then result = "v"
else
if hasMemoryResult()
@@ -344,23 +348,6 @@ class Instruction extends Construction::TInstruction {
)
}
bindingset[type]
private string getValueCategoryString(string type) {
if isGLValue() then result = "glval<" + type + ">" else result = type
}
string getResultTypeString() {
exists(string valcat |
valcat = getValueCategoryString(getResultType().toString()) and
if
getResultType() instanceof Language::UnknownType and
not isGLValue() and
exists(getResultSize())
then result = valcat + "[" + getResultSize().toString() + "]"
else result = valcat
)
}
/**
* Gets a human-readable string that uniquely identifies this instruction
* within the function. This string is used to refer to this instruction when
@@ -380,7 +367,9 @@ class Instruction extends Construction::TInstruction {
*
* Example: `r1_1(int*)`
*/
final string getResultString() { result = getResultId() + "(" + getResultTypeString() + ")" }
final string getResultString() {
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
}
/**
* Gets a string describing the operands of this instruction, suitable for
@@ -448,6 +437,16 @@ class Instruction extends Construction::TInstruction {
result = Construction::getInstructionUnconvertedResultExpression(this)
}
final Language::LanguageType getResultLanguageType() {
result = Construction::getInstructionResultType(this)
}
/**
* Gets the type of the result produced by this instruction. If the instruction does not produce
* a result, its result type will be `IRVoidType`.
*/
final IRType getResultIRType() { result = getResultLanguageType().getIRType() }
/**
* Gets the type of the result produced by this instruction. If the
* instruction does not produce a result, its result type will be `VoidType`.
@@ -455,7 +454,15 @@ class Instruction extends Construction::TInstruction {
* If `isGLValue()` holds, then the result type of this instruction should be
* thought of as "pointer to `getResultType()`".
*/
final Language::Type getResultType() { Construction::instructionHasType(this, result, _) }
final Language::Type getResultType() {
exists(Language::LanguageType resultType |
resultType = getResultLanguageType() and
(
resultType.hasUnspecifiedType(result, _) or
not resultType.hasUnspecifiedType(_, _) and result instanceof Language::UnknownType
)
)
}
/**
* Holds if the result produced by this instruction is a glvalue. If this
@@ -475,7 +482,9 @@ class Instruction extends Construction::TInstruction {
* result of the `Load` instruction is a prvalue of type `int`, representing
* the integer value loaded from variable `x`.
*/
final predicate isGLValue() { Construction::instructionHasType(this, _, true) }
final predicate isGLValue() {
Construction::getInstructionResultType(this).hasType(_, true)
}
/**
* Gets the size of the result produced by this instruction, in bytes. If the
@@ -485,14 +494,7 @@ class Instruction extends Construction::TInstruction {
* `getResultSize()` will always be the size of a pointer.
*/
final int getResultSize() {
if isGLValue()
then
// a glvalue is always pointer-sized.
result = Language::getPointerSize()
else
if getResultType() instanceof Language::UnknownType
then result = Construction::getInstructionResultSize(this)
else result = Language::getTypeSize(getResultType())
result = Construction::getInstructionResultType(this).getByteSize()
}
/**
@@ -1300,7 +1302,7 @@ class CatchInstruction extends Instruction {
* An instruction that catches an exception of a specific type.
*/
class CatchByTypeInstruction extends CatchInstruction {
Language::Type exceptionType;
Language::LanguageType exceptionType;
CatchByTypeInstruction() {
getOpcode() instanceof Opcode::CatchByType and
@@ -1312,7 +1314,7 @@ class CatchByTypeInstruction extends CatchInstruction {
/**
* Gets the type of exception to be caught.
*/
final Language::Type getExceptionType() { result = exceptionType }
final Language::LanguageType getExceptionType() { result = exceptionType }
}
/**

View File

@@ -1,9 +1,10 @@
private import internal.IRInternal
import Instruction
import IRBlock
private import Instruction
private import IRBlock
private import internal.OperandImports as Imports
import Imports::MemoryAccessKind
import Imports::Overlap
private import Imports::MemoryAccessKind
private import Imports::IRType
private import Imports::Overlap
private import Imports::OperandTag
cached
@@ -143,22 +144,40 @@ class Operand extends TOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
Language::Type getType() { result = getAnyDef().getResultType() }
Language::LanguageType getLanguageType() { result = getAnyDef().getResultLanguageType() }
/**
* Gets the language-neutral type of the value consumed by this operand. This is usually the same
* as the result type of the definition instruction consumed by this operand. For register
* operands, this is always the case. For some memory operands, the operand type may be different
* from the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
final IRType getIRType() { result = getLanguageType().getIRType() }
/**
* Gets the type of the value consumed by this operand. This is usually the same as the
* result type of the definition instruction consumed by this operand. For register operands,
* this is always the case. For some memory operands, the operand type may be different from
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
final Language::Type getType() { getLanguageType().hasType(result, _) }
/**
* Holds if the value consumed by this operand is a glvalue. If this
* holds, the value of the operand represents the address of a location,
* and the type of the location is given by `getType()`. If this does
* not hold, the value of the operand represents a value whose type is
* given by `getResultType()`.
* given by `getType()`.
*/
predicate isGLValue() { getAnyDef().isGLValue() }
final predicate isGLValue() { getLanguageType().hasType(_, true) }
/**
* Gets the size of the value consumed by this operand, in bytes. If the operand does not have
* a known constant size, this predicate does not hold.
*/
int getSize() { result = Language::getTypeSize(getType()) }
final int getSize() { result = getLanguageType().getByteSize() }
}
/**
@@ -170,11 +189,6 @@ class MemoryOperand extends Operand {
this = TPhiOperand(_, _, _, _)
}
override predicate isGLValue() {
// A `MemoryOperand` can never be a glvalue
none()
}
/**
* Gets the kind of memory access performed by the operand.
*/
@@ -239,7 +253,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
class TypedOperand extends NonPhiMemoryOperand {
override TypedOperandTag tag;
final override Language::Type getType() {
final override Language::LanguageType getLanguageType() {
result = Construction::getInstructionOperandType(useInstr, tag)
}
}
@@ -371,12 +385,6 @@ class PositionalArgumentOperand extends ArgumentOperand {
class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
final override int getSize() {
if getType() instanceof Language::UnknownType
then result = Construction::getInstructionOperandSize(useInstr, tag)
else result = Language::getTypeSize(getType())
}
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess

View File

@@ -1,2 +1,3 @@
import semmle.code.csharp.ir.implementation.EdgeKind as EdgeKind
import semmle.code.csharp.ir.implementation.IRType as IRType
import semmle.code.csharp.ir.implementation.MemoryAccessKind as MemoryAccessKind

View File

@@ -1,3 +1,4 @@
import semmle.code.csharp.ir.implementation.IRType as IRType
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

View File

@@ -1,4 +1,5 @@
import semmle.code.csharp.ir.implementation.EdgeKind as EdgeKind
import semmle.code.csharp.ir.implementation.IRType as IRType
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

View File

@@ -1,3 +1,4 @@
import semmle.code.csharp.ir.implementation.MemoryAccessKind as MemoryAccessKind
import semmle.code.csharp.ir.implementation.IRType as IRType
import semmle.code.csharp.ir.internal.Overlap as Overlap
import semmle.code.csharp.ir.implementation.internal.OperandTag as OperandTag

View File

@@ -4,34 +4,52 @@ private import Alias
private import SSAConstruction
private import DebugSSA
bindingset[offset]
private string getKeySuffixForOffset(int offset) {
if offset % 2 = 0 then result = "" else result = "_Chi"
}
bindingset[offset]
private int getIndexForOffset(int offset) { result = offset / 2 }
/**
* Property provide that dumps the memory access of each result. Useful for debugging SSA
* construction.
*/
class PropertyProvider extends IRPropertyProvider {
override string getInstructionProperty(Instruction instruction, string key) {
exists(MemoryLocation location |
location = getResultMemoryLocation(instruction) and
(
key = "ResultMemoryLocation" and result = location.toString()
or
key = "ResultVirtualVariable" and result = location.getVirtualVariable().toString()
key = "ResultMemoryLocation" and
result = strictconcat(MemoryLocation loc |
loc = getResultMemoryLocation(instruction)
|
loc.toString(), ","
)
)
or
exists(MemoryLocation location |
location = getOperandMemoryLocation(instruction.getAnOperand()) and
(
key = "OperandMemoryAccess" and result = location.toString()
or
key = "OperandVirtualVariable" and result = location.getVirtualVariable().toString()
key = "ResultVirtualVariable" and
result = strictconcat(MemoryLocation loc |
loc = getResultMemoryLocation(instruction)
|
loc.getVirtualVariable().toString(), ","
)
)
or
exists(MemoryLocation useLocation, IRBlock defBlock, int defRank, int defIndex |
hasDefinitionAtRank(useLocation, _, defBlock, defRank, defIndex) and
defBlock.getInstruction(defIndex) = instruction and
key = "DefinitionRank[" + useLocation.toString() + "]" and
key = "OperandMemoryLocation" and
result = strictconcat(MemoryLocation loc |
loc = getOperandMemoryLocation(instruction.getAnOperand())
|
loc.toString(), ","
)
or
key = "OperandVirtualVariable" and
result = strictconcat(MemoryLocation loc |
loc = getOperandMemoryLocation(instruction.getAnOperand())
|
loc.getVirtualVariable().toString(), ","
)
or
exists(MemoryLocation useLocation, IRBlock defBlock, int defRank, int defOffset |
hasDefinitionAtRank(useLocation, _, defBlock, defRank, defOffset) and
defBlock.getInstruction(getIndexForOffset(defOffset)) = instruction and
key = "DefinitionRank" + getKeySuffixForOffset(defOffset) + "[" + useLocation.toString() + "]" and
result = defRank.toString()
)
or
@@ -41,10 +59,11 @@ class PropertyProvider extends IRPropertyProvider {
result = useRank.toString()
)
or
exists(MemoryLocation useLocation, IRBlock defBlock, int defRank, int defIndex |
hasDefinitionAtRank(useLocation, _, defBlock, defRank, defIndex) and
defBlock.getInstruction(defIndex) = instruction and
key = "DefinitionReachesUse[" + useLocation.toString() + "]" and
exists(MemoryLocation useLocation, IRBlock defBlock, int defRank, int defOffset |
hasDefinitionAtRank(useLocation, _, defBlock, defRank, defOffset) and
defBlock.getInstruction(getIndexForOffset(defOffset)) = instruction and
key = "DefinitionReachesUse" + getKeySuffixForOffset(defOffset) + "[" + useLocation.toString()
+ "]" and
result = strictconcat(IRBlock useBlock, int useRank, int useIndex |
exists(Instruction useInstruction |
hasUseAtRank(useLocation, useBlock, useRank, useInstruction) and
@@ -124,3 +143,4 @@ class PropertyProvider extends IRPropertyProvider {
)
}
}

View File

@@ -1,9 +1,6 @@
import SSAConstructionInternal
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 SSAConstructionImports
private import NewIR
private import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
private class OldBlock = Reachability::ReachableBlock;
@@ -51,13 +48,13 @@ private module Cached {
cached
predicate hasTempVariable(
Language::Function func, Language::AST ast, TempVariableTag tag, Language::Type type
Language::Function func, Language::AST ast, TempVariableTag tag, Language::LanguageType type
) {
exists(OldIR::IRTempVariable var |
var.getEnclosingFunction() = func and
var.getAST() = ast and
var.getTag() = tag and
var.getType() = type
var.getLanguageType() = type
)
}
@@ -137,24 +134,12 @@ private module Cached {
}
cached
Language::Type getInstructionOperandType(Instruction instr, TypedOperandTag tag) {
Language::LanguageType getInstructionOperandType(Instruction instr, TypedOperandTag tag) {
exists(OldInstruction oldInstruction, OldIR::TypedOperand oldOperand |
oldInstruction = getOldInstruction(instr) and
oldOperand = oldInstruction.getAnOperand() and
tag = oldOperand.getOperandTag() and
result = oldOperand.getType()
)
}
cached
int getInstructionOperandSize(Instruction instr, SideEffectOperandTag tag) {
exists(OldInstruction oldInstruction, OldIR::SideEffectOperand oldOperand |
oldInstruction = getOldInstruction(instr) and
oldOperand = oldInstruction.getAnOperand() and
tag = oldOperand.getOperandTag() and
// Only return a result for operands that need an explicit result size.
oldOperand.getType() instanceof Language::UnknownType and
result = oldOperand.getSize()
result = oldOperand.getLanguageType()
)
}
@@ -273,29 +258,25 @@ private module Cached {
}
cached
predicate instructionHasType(Instruction instruction, Language::Type type, boolean isGLValue) {
Language::LanguageType getInstructionResultType(Instruction instruction) {
exists(OldInstruction oldInstruction |
instruction = WrappedInstruction(oldInstruction) and
type = oldInstruction.getResultType() and
if oldInstruction.isGLValue() then isGLValue = true else isGLValue = false
result = oldInstruction.getResultLanguageType()
)
or
exists(OldInstruction oldInstruction, Alias::VirtualVariable vvar |
instruction = Chi(oldInstruction) and
hasChiNode(vvar, oldInstruction) and
type = vvar.getType() and
isGLValue = false
result = vvar.getType()
)
or
exists(Alias::MemoryLocation location |
instruction = Phi(_, location) and
type = location.getType() and
isGLValue = false
result = location.getType()
)
or
instruction = Unreached(_) and
type instanceof Language::VoidType and
isGLValue = false
result = Language::getVoidType()
}
cached
@@ -368,7 +349,7 @@ private module Cached {
}
cached
Language::Type getInstructionExceptionType(Instruction instruction) {
Language::LanguageType getInstructionExceptionType(Instruction instruction) {
result = getOldInstruction(instruction).(OldIR::CatchByTypeInstruction).getExceptionType()
}
@@ -377,13 +358,6 @@ private module Cached {
result = getOldInstruction(instruction).(OldIR::PointerArithmeticInstruction).getElementSize()
}
cached
int getInstructionResultSize(Instruction instruction) {
// Only return a result for instructions that needed an explicit result size.
instruction.getResultType() instanceof Language::UnknownType and
result = getOldInstruction(instruction).getResultSize()
}
cached
predicate getInstructionInheritance(
Instruction instruction, Language::Class baseClass, Language::Class derivedClass
@@ -839,7 +813,7 @@ module DefUse {
}
/**
* Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the
* Expose some of the internal predicates to PrintSSA.qll. We do this by publically importing those modules in the
* `DebugSSA` module, which is then imported by PrintSSA.
*/
module DebugSSA {
@@ -884,3 +858,4 @@ private module CachedForDebugging {
result.getTag() = var.getTag()
}
}

View File

@@ -0,0 +1,3 @@
import semmle.code.csharp.ir.implementation.Opcode
import semmle.code.csharp.ir.implementation.internal.OperandTag
import semmle.code.csharp.ir.internal.Overlap

View File

@@ -2,4 +2,5 @@ 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 semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
import SimpleSSA as Alias

View File

@@ -1,24 +1,20 @@
import AliasAnalysis
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 import SimpleSSAImports
private class IntValue = Ints::IntValue;
private predicate hasResultMemoryAccess(
Instruction instr, IRVariable var, Type type, IntValue bitOffset
Instruction instr, IRVariable var, Language::LanguageType type, IntValue bitOffset
) {
resultPointsTo(instr.getResultAddressOperand().getAnyDef(), var, bitOffset) and
type = instr.getResultType()
type = instr.getResultLanguageType()
}
private predicate hasOperandMemoryAccess(
MemoryOperand operand, IRVariable var, Type type, IntValue bitOffset
MemoryOperand operand, IRVariable var, Language::LanguageType type, IntValue bitOffset
) {
resultPointsTo(operand.getAddressOperand().getAnyDef(), var, bitOffset) and
type = operand.getType()
type = operand.getLanguageType()
}
/**
@@ -30,17 +26,17 @@ private predicate isVariableModeled(IRVariable var) {
not variableAddressEscapes(var) and
// There's no need to check for the right size. An `IRVariable` never has an `UnknownType`, so the test for
// `type = var.getType()` is sufficient.
forall(Instruction instr, Type type, IntValue bitOffset |
forall(Instruction instr, Language::LanguageType type, IntValue bitOffset |
hasResultMemoryAccess(instr, var, type, bitOffset)
|
bitOffset = 0 and
type = var.getType()
type.getIRType() = var.getIRType()
) and
forall(MemoryOperand operand, Type type, IntValue bitOffset |
forall(MemoryOperand operand, Language::LanguageType type, IntValue bitOffset |
hasOperandMemoryAccess(operand, var, type, bitOffset)
|
bitOffset = 0 and
type = var.getType()
type.getIRType() = var.getIRType()
)
}
@@ -59,7 +55,7 @@ class MemoryLocation extends TMemoryLocation {
final VirtualVariable getVirtualVariable() { result = this }
final Type getType() { result = var.getType() }
final Language::LanguageType getType() { result = var.getLanguageType() }
final string getUniqueId() { result = var.getUniqueId() }
}
@@ -85,3 +81,4 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
result = getMemoryLocation(var)
)
}

View File

@@ -0,0 +1,5 @@
import semmle.code.csharp.ir.implementation.raw.IR
import semmle.code.csharp.ir.internal.IntegerConstant as Ints
import semmle.code.csharp.ir.implementation.internal.OperandTag
import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
import semmle.code.csharp.ir.internal.Overlap

View File

@@ -13,3 +13,5 @@ containsLoopOfForwardEdges
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
missingCanonicalLanguageType
multipleCanonicalLanguageTypes