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/raw/Instruction.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/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", "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": [ "IR IRBlock": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll", "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/unaliased_ssa/IRBlock.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_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": [ "IR IRVariable": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll", "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/unaliased_ssa/IRVariable.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_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": [ "IR IRFunction": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRFunction.qll", "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/unaliased_ssa/IRFunction.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_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": [ "IR Operand": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll", "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/unaliased_ssa/Operand.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_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": [ "IR IRType": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll", "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/raw/IR.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/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", "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": [ "IR IRSanity": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRSanity.qll", "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/unaliased_ssa/IRSanity.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_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": [ "IR PrintIR": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll", "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/unaliased_ssa/PrintIR.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_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": [ "IR IntegerConstant": [
"cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll", "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/unaliased_ssa/internal/PrintIRImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_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": [ "C++ SSA AliasAnalysis": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll", "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" "cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll"
], ],
"C++ SSA SSAConstruction": [ "IR SSA SimpleSSA": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll", "cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.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/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/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": [ "C++ IR ValueNumber": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll", "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" "cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/PrintDominance.qll"
], ],
"C# IR InstructionImports": [ "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": [ "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": [ "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": [ "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": [ "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": [ "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 private import internal.IRTypeInternal
newtype TIRType = private newtype TIRType =
TIRVoidType() or TIRVoidType() or
TIRUnknownType() or TIRUnknownType() or
TIRErrorType() { TIRErrorType() {

View File

@@ -1,7 +1,5 @@
import SSAConstructionInternal import SSAConstructionInternal
private import semmle.code.cpp.ir.implementation.Opcode private import SSAConstructionImports
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.Overlap
private import NewIR private import NewIR
private class OldBlock = Reachability::ReachableBlock; 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 import SSAConstructionInternal
private import semmle.code.cpp.ir.implementation.Opcode private import SSAConstructionImports
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.Overlap
private import NewIR private import NewIR
private class OldBlock = Reachability::ReachableBlock; 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 import AliasAnalysis
private import semmle.code.cpp.ir.implementation.raw.IR private import SimpleSSAImports
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 class IntValue = Ints::IntValue; 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.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.internal.Overlap as Overlap
import semmle.code.csharp.ir.implementation.internal.OperandTag as OperandTag import semmle.code.csharp.ir.implementation.internal.OperandTag as OperandTag

View File

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

View File

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

View File

@@ -5,6 +5,7 @@ import Imports::TempVariableTag
private import Imports::IRUtilities private import Imports::IRUtilities
private import Imports::TTempVariableTag private import Imports::TTempVariableTag
private import Imports::TIRVariable private import Imports::TIRVariable
private import Imports::IRType
IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var) { IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var) {
result.getVariable() = var and result.getVariable() = var and
@@ -24,7 +25,21 @@ abstract class IRVariable extends TIRVariable {
/** /**
* Gets the type of the variable. * 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 * 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 { class IRUserVariable extends IRVariable, TIRUserVariable {
Language::Variable var; Language::Variable var;
Language::Type type; Language::LanguageType type;
IRUserVariable() { this = TIRUserVariable(var, type, func) } IRUserVariable() { this = TIRUserVariable(var, type, func) }
@@ -71,7 +86,7 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
result = getVariable().toString() + " " + getVariable().getLocation().toString() 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. * Gets the original user-declared variable.
@@ -110,11 +125,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable { class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
Language::AST ast; Language::AST ast;
TempVariableTag tag; TempVariableTag tag;
Language::Type type; Language::LanguageType type;
IRTempVariable() { this = TIRTempVariable(func, ast, tag, 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 } final override Language::AST getAST() { result = ast }

View File

@@ -5,6 +5,7 @@ import IRVariable
import Operand import Operand
private import internal.InstructionImports as Imports private import internal.InstructionImports as Imports
import Imports::EdgeKind import Imports::EdgeKind
import Imports::IRType
import Imports::MemoryAccessKind import Imports::MemoryAccessKind
import Imports::Opcode import Imports::Opcode
private import Imports::OperandTag private import Imports::OperandTag
@@ -113,10 +114,13 @@ module InstructionSanity {
} }
query predicate missingOperandType(Operand operand, string message) { query predicate missingOperandType(Operand operand, string message) {
exists(Language::Function func | exists(Language::Function func, Instruction use |
not exists(operand.getType()) and not exists(operand.getType()) and
func = operand.getUse().getEnclosingFunction() and use = operand.getUse() and
message = "Operand missing type in function '" + Language::getIdentityString(func) + "'." 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() { private string getResultPrefix() {
if getResultType() instanceof Language::VoidType if getResultIRType() instanceof IRVoidType
then result = "v" then result = "v"
else else
if hasMemoryResult() 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 * Gets a human-readable string that uniquely identifies this instruction
* within the function. This string is used to refer to this instruction when * 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*)` * 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 * Gets a string describing the operands of this instruction, suitable for
@@ -448,6 +437,16 @@ class Instruction extends Construction::TInstruction {
result = Construction::getInstructionUnconvertedResultExpression(this) 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 * Gets the type of the result produced by this instruction. If the
* instruction does not produce a result, its result type will be `VoidType`. * 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 * If `isGLValue()` holds, then the result type of this instruction should be
* thought of as "pointer to `getResultType()`". * 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 * 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 * result of the `Load` instruction is a prvalue of type `int`, representing
* the integer value loaded from variable `x`. * 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 * 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. * `getResultSize()` will always be the size of a pointer.
*/ */
final int getResultSize() { final int getResultSize() {
if isGLValue() result = Construction::getInstructionResultType(this).getByteSize()
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())
} }
/** /**
@@ -1300,7 +1302,7 @@ class CatchInstruction extends Instruction {
* An instruction that catches an exception of a specific type. * An instruction that catches an exception of a specific type.
*/ */
class CatchByTypeInstruction extends CatchInstruction { class CatchByTypeInstruction extends CatchInstruction {
Language::Type exceptionType; Language::LanguageType exceptionType;
CatchByTypeInstruction() { CatchByTypeInstruction() {
getOpcode() instanceof Opcode::CatchByType and getOpcode() instanceof Opcode::CatchByType and
@@ -1312,7 +1314,7 @@ class CatchByTypeInstruction extends CatchInstruction {
/** /**
* Gets the type of exception to be caught. * 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 private import internal.IRInternal
import Instruction private import Instruction
import IRBlock private import IRBlock
private import internal.OperandImports as Imports private import internal.OperandImports as Imports
import Imports::MemoryAccessKind private import Imports::MemoryAccessKind
import Imports::Overlap private import Imports::IRType
private import Imports::Overlap
private import Imports::OperandTag private import Imports::OperandTag
cached 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 * 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. * 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 if the value consumed by this operand is a glvalue. If this
* holds, the value of the operand represents the address of a location, * 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 * 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 * 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 * 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. * 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(_, _, _, _) this = TPhiOperand(_, _, _, _)
} }
override predicate isGLValue() {
// A `MemoryOperand` can never be a glvalue
none()
}
/** /**
* Gets the kind of memory access performed by the operand. * Gets the kind of memory access performed by the operand.
*/ */
@@ -239,7 +253,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
class TypedOperand extends NonPhiMemoryOperand { class TypedOperand extends NonPhiMemoryOperand {
override TypedOperandTag tag; override TypedOperandTag tag;
final override Language::Type getType() { final override Language::LanguageType getLanguageType() {
result = Construction::getInstructionOperandType(useInstr, tag) result = Construction::getInstructionOperandType(useInstr, tag)
} }
} }
@@ -371,12 +385,6 @@ class PositionalArgumentOperand extends ArgumentOperand {
class SideEffectOperand extends TypedOperand { class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag; 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() { override MemoryAccessKind getMemoryAccess() {
useInstr instanceof CallSideEffectInstruction and useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess result instanceof EscapedMayMemoryAccess

View File

@@ -1,2 +1,3 @@
import semmle.code.csharp.ir.implementation.EdgeKind as EdgeKind 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.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.implementation.TempVariableTag as TempVariableTag
import semmle.code.csharp.ir.internal.IRUtilities as IRUtilities import semmle.code.csharp.ir.internal.IRUtilities as IRUtilities
import semmle.code.csharp.ir.internal.TempVariableTag as TTempVariableTag 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.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.MemoryAccessKind as MemoryAccessKind
import semmle.code.csharp.ir.implementation.Opcode as Opcode import semmle.code.csharp.ir.implementation.Opcode as Opcode
import semmle.code.csharp.ir.implementation.internal.OperandTag as OperandTag 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.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.internal.Overlap as Overlap
import semmle.code.csharp.ir.implementation.internal.OperandTag as OperandTag import semmle.code.csharp.ir.implementation.internal.OperandTag as OperandTag

View File

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

View File

@@ -1,9 +1,6 @@
import SSAConstructionInternal import SSAConstructionInternal
private import semmle.code.csharp.ir.implementation.Opcode private import SSAConstructionImports
private import semmle.code.csharp.ir.implementation.internal.OperandTag
private import semmle.code.csharp.ir.internal.Overlap
private import NewIR private import NewIR
private import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
private class OldBlock = Reachability::ReachableBlock; private class OldBlock = Reachability::ReachableBlock;
@@ -51,13 +48,13 @@ private module Cached {
cached cached
predicate hasTempVariable( 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 | exists(OldIR::IRTempVariable var |
var.getEnclosingFunction() = func and var.getEnclosingFunction() = func and
var.getAST() = ast and var.getAST() = ast and
var.getTag() = tag and var.getTag() = tag and
var.getType() = type var.getLanguageType() = type
) )
} }
@@ -137,24 +134,12 @@ private module Cached {
} }
cached cached
Language::Type getInstructionOperandType(Instruction instr, TypedOperandTag tag) { Language::LanguageType getInstructionOperandType(Instruction instr, TypedOperandTag tag) {
exists(OldInstruction oldInstruction, OldIR::TypedOperand oldOperand | exists(OldInstruction oldInstruction, OldIR::TypedOperand oldOperand |
oldInstruction = getOldInstruction(instr) and oldInstruction = getOldInstruction(instr) and
oldOperand = oldInstruction.getAnOperand() and oldOperand = oldInstruction.getAnOperand() and
tag = oldOperand.getOperandTag() and tag = oldOperand.getOperandTag() and
result = oldOperand.getType() result = oldOperand.getLanguageType()
)
}
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()
) )
} }
@@ -273,29 +258,25 @@ private module Cached {
} }
cached cached
predicate instructionHasType(Instruction instruction, Language::Type type, boolean isGLValue) { Language::LanguageType getInstructionResultType(Instruction instruction) {
exists(OldInstruction oldInstruction | exists(OldInstruction oldInstruction |
instruction = WrappedInstruction(oldInstruction) and instruction = WrappedInstruction(oldInstruction) and
type = oldInstruction.getResultType() and result = oldInstruction.getResultLanguageType()
if oldInstruction.isGLValue() then isGLValue = true else isGLValue = false
) )
or or
exists(OldInstruction oldInstruction, Alias::VirtualVariable vvar | exists(OldInstruction oldInstruction, Alias::VirtualVariable vvar |
instruction = Chi(oldInstruction) and instruction = Chi(oldInstruction) and
hasChiNode(vvar, oldInstruction) and hasChiNode(vvar, oldInstruction) and
type = vvar.getType() and result = vvar.getType()
isGLValue = false
) )
or or
exists(Alias::MemoryLocation location | exists(Alias::MemoryLocation location |
instruction = Phi(_, location) and instruction = Phi(_, location) and
type = location.getType() and result = location.getType()
isGLValue = false
) )
or or
instruction = Unreached(_) and instruction = Unreached(_) and
type instanceof Language::VoidType and result = Language::getVoidType()
isGLValue = false
} }
cached cached
@@ -368,7 +349,7 @@ private module Cached {
} }
cached cached
Language::Type getInstructionExceptionType(Instruction instruction) { Language::LanguageType getInstructionExceptionType(Instruction instruction) {
result = getOldInstruction(instruction).(OldIR::CatchByTypeInstruction).getExceptionType() result = getOldInstruction(instruction).(OldIR::CatchByTypeInstruction).getExceptionType()
} }
@@ -377,13 +358,6 @@ private module Cached {
result = getOldInstruction(instruction).(OldIR::PointerArithmeticInstruction).getElementSize() 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 cached
predicate getInstructionInheritance( predicate getInstructionInheritance(
Instruction instruction, Language::Class baseClass, Language::Class derivedClass 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. * `DebugSSA` module, which is then imported by PrintSSA.
*/ */
module DebugSSA { module DebugSSA {
@@ -884,3 +858,4 @@ private module CachedForDebugging {
result.getTag() = var.getTag() 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.ReachableBlock as Reachability
import semmle.code.csharp.ir.implementation.raw.internal.reachability.Dominance as Dominance 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.implementation.unaliased_ssa.IR as NewIR
import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
import SimpleSSA as Alias import SimpleSSA as Alias

View File

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