Merge pull request #1607 from dave-bartolomeo/dave/CrossLanguageIR

C++: Start preparing IR for supporting multiple languages
This commit is contained in:
Robert Marsh
2019-07-29 12:34:21 -07:00
committed by GitHub
83 changed files with 639 additions and 512 deletions

View File

@@ -21,46 +21,76 @@
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll"
],
"C++ IR Instruction": [
"IR Instruction": [
"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"
],
"C++ IR IRBlock": [
"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"
],
"C++ IR IRVariable": [
"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"
],
"C++ IR IRFunction": [
"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"
],
"C++ IR Operand": [
"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"
],
"C++ IR IRImpl": [
"IR IR": [
"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"
],
"C++ IR IRSanityImpl": [
"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"
],
"C++ IR PrintIRImpl": [
"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"
],
"C++ IR InstructionImports": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/InstructionImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/InstructionImports.qll"
],
"C++ IR IRImports": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRImports.qll"
],
"C++ IR IRBlockImports": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRBlockImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRBlockImports.qll"
],
"C++ IR IRVariableImports": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRVariableImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRVariableImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRVariableImports.qll"
],
"C++ IR OperandImports": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/OperandImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/OperandImports.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/OperandImports.qll"
],
"C++ IR PrintIRImports": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/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"
],
"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"

View File

@@ -16,6 +16,7 @@
* LGTM until its performance is well understood.
*/
import cpp
import semmle.code.cpp.ir.IR
import semmle.code.cpp.ir.ValueNumbering

View File

@@ -1,19 +1 @@
import cpp
private newtype TIRConfiguration = MkIRConfiguration()
/**
* The query can extend this class to control which functions have IR generated for them.
*/
class IRConfiguration extends TIRConfiguration {
string toString() {
result = "IRConfiguration"
}
/**
* Holds if IR should be created for function `func`. By default, holds for all functions.
*/
predicate shouldCreateIRForFunction(Function func) {
any()
}
}
import implementation.IRConfiguration

View File

@@ -1,3 +1,4 @@
private import cpp
private import semmle.code.cpp.ir.IR
Function viableImpl(CallInstruction call) { result = viableCallable(call) }

View File

@@ -1,4 +1,4 @@
import cpp
private import internal.EdgeKindInternal
private newtype TEdgeKind =
TGotoEdge() or // Single successor (including fall-through)
@@ -7,9 +7,7 @@ private newtype TEdgeKind =
TExceptionEdge() or // Thrown exception
TDefaultEdge() or // 'default' label of switch
TCaseEdge(string minValue, string maxValue) { // Case label of switch
exists(SwitchCase switchCase |
hasCaseEdge(switchCase, minValue, maxValue)
)
Language::hasCaseEdge(minValue, maxValue)
}
/**
@@ -122,20 +120,3 @@ class CaseEdge extends EdgeKind, TCaseEdge {
CaseEdge caseEdge(string minValue, string maxValue) {
result = TCaseEdge(minValue, maxValue)
}
private predicate hasCaseEdge(SwitchCase switchCase, string minValue,
string maxValue) {
minValue = switchCase.getExpr().getFullyConverted().getValue() and
if exists(switchCase.getEndExpr()) then
maxValue = switchCase.getEndExpr().getFullyConverted().getValue()
else
maxValue = minValue
}
EdgeKind getCaseEdge(SwitchCase switchCase) {
exists(CaseEdge edge |
result = edge and
hasCaseEdge(switchCase, edge.getMinValue(), edge.getMaxValue())
) or
(switchCase instanceof DefaultCase and result instanceof DefaultEdge)
}

View File

@@ -0,0 +1,19 @@
private import internal.IRConfigurationInternal
private newtype TIRConfiguration = MkIRConfiguration()
/**
* The query can extend this class to control which functions have IR generated for them.
*/
class IRConfiguration extends TIRConfiguration {
string toString() {
result = "IRConfiguration"
}
/**
* Holds if IR should be created for function `func`. By default, holds for all functions.
*/
predicate shouldCreateIRForFunction(Language::Function func) {
any()
}
}

View File

@@ -1,5 +1,3 @@
import cpp
private newtype TMemoryAccessKind =
TIndirectMemoryAccess() or
TIndirectMayMemoryAccess() or

View File

@@ -1,4 +1,3 @@
import cpp
private import semmle.code.cpp.ir.internal.TempVariableTag
class TempVariableTag extends TTempVariableTag {

View File

@@ -1,44 +0,0 @@
import cpp
private newtype TValueCategory =
TLValue() or
TXValue() or
TPRValue()
abstract class ValueCategory extends TValueCategory {
abstract string toString();
}
abstract class GLValue extends ValueCategory {
}
abstract class RValue extends ValueCategory {
}
class LValue extends GLValue, TLValue {
override string toString() {
result = "lvalue"
}
}
class XValue extends GLValue, RValue, TXValue {
override string toString() {
result = "xvalue"
}
}
class PRValue extends RValue, TPRValue {
override string toString() {
result = "prvalue"
}
}
ValueCategory getExprValueCategory(Expr expr) {
(
expr.isLValueCategory() and result instanceof LValue
) or (
expr.isXValueCategory() and result instanceof XValue
) or (
expr.isPRValueCategory() and result instanceof PRValue
)
}

View File

@@ -3,8 +3,9 @@ import Instruction
import IRBlock
import IRVariable
import Operand
import semmle.code.cpp.ir.implementation.EdgeKind
import semmle.code.cpp.ir.implementation.MemoryAccessKind
private import internal.IRImports as Imports
import Imports::EdgeKind
import Imports::MemoryAccessKind
private newtype TIRPropertyProvider = MkIRPropertyProvider()

View File

@@ -1,6 +1,7 @@
private import internal.IRInternal
import Instruction
import semmle.code.cpp.ir.implementation.EdgeKind
private import internal.IRBlockImports as Imports
import Imports::EdgeKind
private import Cached
/**
@@ -19,7 +20,7 @@ class IRBlockBase extends TIRBlock {
result = getFirstInstruction(this).toString()
}
final Location getLocation() {
final Language::Location getLocation() {
result = getFirstInstruction().getLocation()
}
@@ -67,7 +68,7 @@ class IRBlockBase extends TIRBlock {
result = getFirstInstruction(this).getEnclosingIRFunction()
}
final Function getEnclosingFunction() {
final Language::Function getEnclosingFunction() {
result = getFirstInstruction(this).getEnclosingFunction()
}
}

View File

@@ -1,9 +1,8 @@
private import internal.IRInternal
import Instruction
import cpp
private newtype TIRFunction =
MkIRFunction(Function func) {
MkIRFunction(Language::Function func) {
Construction::functionHasIR(func)
}
@@ -11,7 +10,7 @@ private newtype TIRFunction =
* Represents the IR for a function.
*/
class IRFunction extends TIRFunction {
Function func;
Language::Function func;
IRFunction() {
this = MkIRFunction(func)
@@ -24,14 +23,14 @@ class IRFunction extends TIRFunction {
/**
* Gets the function whose IR is represented.
*/
final Function getFunction() {
final Language::Function getFunction() {
result = func
}
/**
* Gets the location of the function.
*/
final Location getLocation() {
final Language::Location getLocation() {
result = func.getLocation()
}

View File

@@ -1,12 +1,12 @@
private import internal.IRInternal
import IRFunction
import cpp
import semmle.code.cpp.ir.implementation.TempVariableTag
private import semmle.code.cpp.ir.internal.IRUtilities
private import semmle.code.cpp.ir.internal.TempVariableTag
private import semmle.code.cpp.ir.internal.TIRVariable
private import internal.IRVariableImports as Imports
import Imports::TempVariableTag
private import Imports::IRUtilities
private import Imports::TTempVariableTag
private import Imports::TIRVariable
IRUserVariable getIRUserVariable(Function func, Variable var) {
IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var) {
result.getVariable() = var and
result.getEnclosingFunction() = func
}
@@ -17,20 +17,20 @@ IRUserVariable getIRUserVariable(Function func, Variable var) {
* generated by the AST-to-IR translation (`IRTempVariable`).
*/
abstract class IRVariable extends TIRVariable {
Function func;
Language::Function func;
abstract string toString();
/**
* Gets the type of the variable.
*/
abstract Type getType();
abstract Language::Type getType();
/**
* Gets the AST node that declared this variable, or that introduced this
* variable as part of the AST-to-IR translation.
*/
abstract Locatable getAST();
abstract Language::AST getAST();
/**
* Gets an identifier string for the variable. This identifier is unique
@@ -41,7 +41,7 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the source location of this variable.
*/
final Location getLocation() {
final Language::Location getLocation() {
result = getAST().getLocation()
}
@@ -55,7 +55,7 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the function that references this variable.
*/
final Function getEnclosingFunction() {
final Language::Function getEnclosingFunction() {
result = func
}
}
@@ -63,29 +63,34 @@ abstract class IRVariable extends TIRVariable {
/**
* Represents a user-declared variable referenced by the IR for a function.
*/
abstract class IRUserVariable extends IRVariable {
Variable var;
class IRUserVariable extends IRVariable, TIRUserVariable {
Language::Variable var;
Language::Type type;
IRUserVariable() {
this = TIRUserVariable(var, type, func)
}
override final string toString() {
result = var.toString()
result = getVariable().toString()
}
override final Type getType() {
result = getVariableType(var)
}
override final Locatable getAST() {
override final Language::AST getAST() {
result = var
}
override final string getUniqueId() {
result = var.toString() + " " + var.getLocation().toString()
result = getVariable().toString() + " " + getVariable().getLocation().toString()
}
override final Language::Type getType() {
result = type
}
/**
* Gets the original user-declared variable.
*/
final Variable getVariable() {
Language::Variable getVariable() {
result = var
}
}
@@ -98,45 +103,49 @@ abstract class IRUserVariable extends IRVariable {
abstract class IRAutomaticVariable extends IRVariable {
}
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable,
TIRAutomaticUserVariable {
LocalScopeVariable localVar;
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
IRAutomaticUserVariable() {
this = TIRAutomaticUserVariable(localVar, func) and
var = localVar
Language::isVariableAutomatic(var)
}
final LocalScopeVariable getLocalVariable() {
result = localVar
final override Language::AutomaticVariable getVariable() {
result = var
}
}
class IRStaticUserVariable extends IRUserVariable, TIRStaticUserVariable {
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
IRStaticUserVariable() {
this = TIRStaticUserVariable(var, func)
not Language::isVariableAutomatic(var)
}
final override Language::StaticVariable getVariable() {
result = var
}
}
IRTempVariable getIRTempVariable(Locatable ast, TempVariableTag tag) {
IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getAST() = ast and
result.getTag() = tag
}
class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
Locatable ast;
Language::AST ast;
TempVariableTag tag;
Type type;
Language::Type type;
IRTempVariable() {
this = TIRTempVariable(func, ast, tag, type)
}
override final Type getType() {
override final Language::Type getType() {
result = type
}
override final Locatable getAST() {
override final Language::AST getAST() {
result = ast
}

View File

@@ -3,13 +3,11 @@ import IRFunction
import IRBlock
import IRVariable
import Operand
import cpp
import semmle.code.cpp.ir.implementation.EdgeKind
import semmle.code.cpp.ir.implementation.MemoryAccessKind
import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.Print
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import internal.InstructionImports as Imports
import Imports::EdgeKind
import Imports::MemoryAccessKind
import Imports::Opcode
private import Imports::OperandTag
module InstructionSanity {
/**
@@ -60,7 +58,7 @@ module InstructionSanity {
message = "Instruction '" + instr.getOpcode().toString() + "' is missing an expected operand with tag '" +
tag.toString() + "' in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = getIdentityString(func.getFunction())
funcText = Language::getIdentityString(func.getFunction())
)
}
@@ -101,10 +99,10 @@ module InstructionSanity {
}
query predicate missingOperandType(Operand operand, string message) {
exists(Function func |
exists(Language::Function func |
not exists(operand.getType()) and
func = operand.getUse().getEnclosingFunction() and
message = "Operand missing type in function '" + getIdentityString(func) + "'."
message = "Operand missing type in function '" + Language::getIdentityString(func) + "'."
)
}
@@ -135,14 +133,13 @@ module InstructionSanity {
* Holds if `instr` in `f` is part of a loop even though the AST of `f`
* contains no element that can cause loops.
*/
query predicate unexplainedLoop(Function f, Instruction instr) {
query predicate unexplainedLoop(Language::Function f, Instruction instr) {
exists(IRBlock block |
instr.getBlock() = block and
block.getEnclosingFunction() = f and
block.getASuccessor+() = block
) and
not exists(Loop l | l.getEnclosingFunction() = f) and
not exists(GotoStmt s | s.getEnclosingFunction() = f)
not Language::hasPotentialLoop(f)
}
/**
@@ -201,7 +198,7 @@ module InstructionSanity {
entry = f.getEntryBlock() and
entry.getASuccessor+() = block and
not forwardEdge+(entry, block) and
not exists(GotoStmt s | s.getEnclosingFunction() = f.getFunction())
not Language::hasGoto(f.getFunction())
)
}
@@ -209,7 +206,7 @@ module InstructionSanity {
* Holds if the number of back edges differs between the `Instruction` graph
* and the `IRBlock` graph.
*/
query predicate backEdgeCountMismatch(Function f, int fromInstr, int fromBlock) {
query predicate backEdgeCountMismatch(Language::Function f, int fromInstr, int fromBlock) {
fromInstr = count(Instruction i1, Instruction i2 |
i1.getEnclosingFunction() = f and i1.getBackEdgeSuccessor(_) = i2
) and
@@ -266,7 +263,7 @@ class Instruction extends Construction::TInstruction {
}
private string getResultPrefix() {
if getResultType() instanceof VoidType then
if getResultType() instanceof Language::VoidType then
result = "v"
else if hasMemoryResult() then
if isResultModeled() then
@@ -312,7 +309,7 @@ class Instruction extends Construction::TInstruction {
string getResultTypeString() {
exists(string valcat |
valcat = getValueCategoryString(getResultType().toString()) and
if (getResultType() instanceof UnknownType and
if (getResultType() instanceof Language::UnknownType and
not isGLValue() and
exists(getResultSize())) then (
result = valcat + "[" + getResultSize().toString() + "]"
@@ -379,7 +376,7 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the function that contains this instruction.
*/
final Function getEnclosingFunction() {
final Language::Function getEnclosingFunction() {
result = getEnclosingIRFunction().getFunction()
}
@@ -393,28 +390,28 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the AST that caused this instruction to be generated.
*/
final Locatable getAST() {
final Language::AST getAST() {
result = Construction::getInstructionAST(this)
}
/**
* Gets the location of the source code for this instruction.
*/
final Location getLocation() {
final Language::Location getLocation() {
result = getAST().getLocation()
}
/**
* Gets the `Expr` whose result is computed by this instruction, if any.
*/
final Expr getConvertedResultExpression() {
final Language::Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the unconverted `Expr` whose result is computed by this instruction, if any.
*/
final Expr getUnconvertedResultExpression() {
final Language::Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)
}
@@ -425,7 +422,7 @@ class Instruction extends Construction::TInstruction {
* If `isGLValue()` holds, then the result type of this instruction should be
* thought of as "pointer to `getResultType()`".
*/
final Type getResultType() {
final Language::Type getResultType() {
Construction::instructionHasType(this, result, _)
}
@@ -461,11 +458,9 @@ class Instruction extends Construction::TInstruction {
final int getResultSize() {
if isGLValue() then (
// a glvalue is always pointer-sized.
exists(NullPointerType nullptr |
result = nullptr.getSize()
)
result = Language::getPointerSize()
)
else if getResultType() instanceof UnknownType then
else if getResultType() instanceof Language::UnknownType then
result = Construction::getInstructionResultSize(this)
else (
result = getResultType().getSize()
@@ -616,7 +611,7 @@ class VariableInstruction extends Instruction {
}
class FieldInstruction extends Instruction {
Field field;
Language::Field field;
FieldInstruction() {
field = Construction::getInstructionField(this)
@@ -626,13 +621,13 @@ class FieldInstruction extends Instruction {
result = field.toString()
}
final Field getField() {
final Language::Field getField() {
result = field
}
}
class FunctionInstruction extends Instruction {
Function funcSymbol;
Language::Function funcSymbol;
FunctionInstruction() {
funcSymbol = Construction::getInstructionFunction(this)
@@ -642,7 +637,7 @@ class FunctionInstruction extends Instruction {
result = funcSymbol.toString()
}
final Function getFunctionSymbol() {
final Language::Function getFunctionSymbol() {
result = funcSymbol
}
}
@@ -680,7 +675,7 @@ class InitializeParameterInstruction extends VariableInstruction {
getOpcode() instanceof Opcode::InitializeParameter
}
final Parameter getParameter() {
final Language::Parameter getParameter() {
result = var.(IRUserVariable).getVariable()
}
@@ -738,9 +733,9 @@ class UninitializedInstruction extends VariableInstruction {
}
/**
* Gets the `LocalVariable` that is uninitialized.
* Gets the variable that is uninitialized.
*/
final LocalVariable getLocalVariable() {
final Language::Variable getLocalVariable() {
result = var.(IRUserVariable).getVariable()
}
}
@@ -877,28 +872,28 @@ class ConstantInstruction extends ConstantValueInstruction {
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
getResultType() instanceof IntegralType
getResultType() instanceof Language::IntegralType
}
}
class FloatConstantInstruction extends ConstantInstruction {
FloatConstantInstruction() {
getResultType() instanceof FloatingPointType
getResultType() instanceof Language::FloatingPointType
}
}
class StringConstantInstruction extends Instruction {
StringLiteral value;
Language::StringLiteral value;
StringConstantInstruction() {
value = Construction::getInstructionStringLiteral(this)
}
override final string getImmediateString() {
result = value.getValueText().replaceAll("\n", " ").replaceAll("\r", "").replaceAll("\t", " ")
result = Language::getStringLiteralText(value)
}
final StringLiteral getValue() {
final Language::StringLiteral getValue() {
result = value
}
}
@@ -1086,8 +1081,8 @@ class ConvertInstruction extends UnaryInstruction {
* related by inheritance.
*/
class InheritanceConversionInstruction extends UnaryInstruction {
Class baseClass;
Class derivedClass;
Language::Class baseClass;
Language::Class derivedClass;
InheritanceConversionInstruction() {
Construction::getInstructionInheritance(this, baseClass, derivedClass)
@@ -1102,7 +1097,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* the base and derived classes. This predicate does not hold if the
* conversion is to an indirect virtual base class.
*/
final ClassDerivation getDerivation() {
final Language::ClassDerivation getDerivation() {
result.getBaseClass() = baseClass and result.getDerivedClass() = derivedClass
}
@@ -1111,14 +1106,14 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* base class of the derived class, or a virtual base class of the
* derived class.
*/
final Class getBaseClass() {
final Language::Class getBaseClass() {
result = baseClass
}
/**
* Gets the derived class of the conversion.
*/
final Class getDerivedClass() {
final Language::Class getDerivedClass() {
result = derivedClass
}
}
@@ -1349,7 +1344,7 @@ class CallInstruction extends Instruction {
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
final Function getStaticCallTarget() {
final Language::Function getStaticCallTarget() {
result = getCallTarget().(FunctionInstruction).getFunctionSymbol()
}
@@ -1591,7 +1586,7 @@ class CatchInstruction extends Instruction {
* An instruction that catches an exception of a specific type.
*/
class CatchByTypeInstruction extends CatchInstruction {
Type exceptionType;
Language::Type exceptionType;
CatchByTypeInstruction() {
getOpcode() instanceof Opcode::CatchByType and
@@ -1605,7 +1600,7 @@ class CatchByTypeInstruction extends CatchInstruction {
/**
* Gets the type of exception to be caught.
*/
final Type getExceptionType() {
final Language::Type getExceptionType() {
result = exceptionType
}
}

View File

@@ -1,10 +1,10 @@
private import internal.IRInternal
import Instruction
import IRBlock
import cpp
import semmle.code.cpp.ir.implementation.MemoryAccessKind
import semmle.code.cpp.ir.internal.Overlap
private import semmle.code.cpp.ir.internal.OperandTag
private import internal.OperandImports as Imports
import Imports::MemoryAccessKind
import Imports::Overlap
private import Imports::OperandTag
cached
private newtype TOperand =
@@ -50,7 +50,7 @@ class Operand extends TOperand {
result = "Operand"
}
final Location getLocation() {
final Language::Location getLocation() {
result = getUse().getLocation()
}
@@ -166,7 +166,7 @@ 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.
*/
Type getType() {
Language::Type getType() {
result = getAnyDef().getResultType()
}
@@ -284,7 +284,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
class TypedOperand extends NonPhiMemoryOperand {
override TypedOperandTag tag;
override final Type getType() {
override final Language::Type getType() {
result = Construction::getInstructionOperandType(useInstr, tag)
}
}
@@ -447,7 +447,7 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override final int getSize() {
if getType() instanceof UnknownType then
if getType() instanceof Language::UnknownType then
result = Construction::getInstructionOperandSize(useInstr, tag)
else
result = getType().getSize()

View File

@@ -1,7 +1,7 @@
private import internal.IRInternal
private import IR
import cpp
import semmle.code.cpp.ir.IRConfiguration
private import semmle.code.cpp.Print
private import internal.PrintIRImports as Imports
import Imports::IRConfiguration
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
@@ -17,12 +17,12 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
* Holds if the IR for `func` should be printed. By default, holds for all
* functions.
*/
predicate shouldPrintFunction(Function func) {
predicate shouldPrintFunction(Language::Function func) {
any()
}
}
private predicate shouldPrintFunction(Function func) {
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config |
config.shouldPrintFunction(func)
)
@@ -32,7 +32,7 @@ private predicate shouldPrintFunction(Function func) {
* Override of `IRConfiguration` to only create IR for the functions that are to be dumped.
*/
private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldCreateIRForFunction(Function func) {
override predicate shouldCreateIRForFunction(Language::Function func) {
shouldPrintFunction(func)
}
}
@@ -69,7 +69,7 @@ abstract class PrintableIRNode extends TPrintableIRNode {
/**
* Gets the location to be emitted for the node.
*/
abstract Location getLocation();
abstract Language::Location getLocation();
/**
* Gets the label to be emitted for the node.
@@ -126,16 +126,16 @@ class PrintableIRFunction extends PrintableIRNode, TPrintableIRFunction {
result = irFunc.toString()
}
override Location getLocation() {
override Language::Location getLocation() {
result = irFunc.getLocation()
}
override string getLabel() {
result = getIdentityString(irFunc.getFunction())
result = Language::getIdentityString(irFunc.getFunction())
}
override int getOrder() {
this = rank[result + 1](PrintableIRFunction orderedFunc, Location location |
this = rank[result + 1](PrintableIRFunction orderedFunc, Language::Location location |
location = orderedFunc.getIRFunction().getLocation() |
orderedFunc order by location.getFile().getAbsolutePath(), location.getStartLine(),
location.getStartColumn(), orderedFunc.getLabel()
@@ -165,7 +165,7 @@ class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
result = getLabel()
}
override Location getLocation() {
override Language::Location getLocation() {
result = block.getLocation()
}
@@ -213,7 +213,7 @@ class PrintableInstruction extends PrintableIRNode, TPrintableInstruction {
result = instr.toString()
}
override Location getLocation() {
override Language::Location getLocation() {
result = instr.getLocation()
}

View File

@@ -1,5 +1,5 @@
private import internal.ValueNumberingInternal
import cpp
private import cpp
private import IR
/**

View File

@@ -1,5 +1,5 @@
private import AliasAnalysisInternal
import cpp
private import cpp
private import InputIR
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints

View File

@@ -1,11 +1,11 @@
import cpp
private import cpp
import AliasAnalysis
import semmle.code.cpp.ir.internal.Overlap
private import semmle.code.cpp.Print
private import semmle.code.cpp.ir.implementation.unaliased_ssa.IR
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
private import semmle.code.cpp.ir.internal.IntegerInterval as Interval
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private class IntValue = Ints::IntValue;

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.implementation.EdgeKind as EdgeKind

View File

@@ -0,0 +1,2 @@
import semmle.code.cpp.ir.implementation.EdgeKind as EdgeKind
import semmle.code.cpp.ir.implementation.MemoryAccessKind as MemoryAccessKind

View File

@@ -1 +1,2 @@
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
import SSAConstruction as Construction

View File

@@ -0,0 +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

View File

@@ -0,0 +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

View File

@@ -0,0 +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

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.IRConfiguration as IRConfiguration

View File

@@ -1,7 +1,7 @@
import SSAConstructionInternal
import cpp
private import cpp
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.Overlap
private import NewIR

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.internal.IRCppLanguage as Language

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.internal.IRCppLanguage as Language

View File

@@ -1,12 +1,4 @@
import cpp
private int getMaxCallArgIndex() {
result = max(int argIndex |
exists(FunctionCall call |
exists(call.getArgument(argIndex))
)
)
}
private import OperandTagInternal
private newtype TOperandTag =
TAddressOperand() or
@@ -22,17 +14,12 @@ private newtype TOperandTag =
TCallTargetOperand() or
TThisArgumentOperand() or
TPositionalArgumentOperand(int argIndex) {
argIndex in [0..getMaxCallArgIndex()] or
exists(BuiltInOperation op |
exists(op.getChild(argIndex))
)
Language::hasPositionalArgIndex(argIndex)
} or
TChiTotalOperand() or
TChiPartialOperand() or
TAsmOperand(int index) {
exists(AsmStmt asm |
exists(asm.getChild(index))
)
Language::hasAsmOperandIndex(index)
}
/**

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.internal.IRCppLanguage as Language

View File

@@ -0,0 +1,12 @@
private import TIRVariableInternal
private import Imports::TempVariableTag
newtype TIRVariable =
TIRUserVariable(Language::Variable var, Language::Type type,
Language::Function func) {
Construction::hasUserVariable(func, var, type)
} or
TIRTempVariable(Language::Function func, Language::AST ast, TempVariableTag tag,
Language::Type type) {
Construction::hasTempVariable(func, ast, tag, type)
}

View File

@@ -0,0 +1,7 @@
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as Construction
private import semmle.code.cpp.ir.implementation.TempVariableTag as TempVariableTag_
module Imports {
module TempVariableTag = TempVariableTag_;
}

View File

@@ -3,8 +3,9 @@ import Instruction
import IRBlock
import IRVariable
import Operand
import semmle.code.cpp.ir.implementation.EdgeKind
import semmle.code.cpp.ir.implementation.MemoryAccessKind
private import internal.IRImports as Imports
import Imports::EdgeKind
import Imports::MemoryAccessKind
private newtype TIRPropertyProvider = MkIRPropertyProvider()

View File

@@ -1,6 +1,7 @@
private import internal.IRInternal
import Instruction
import semmle.code.cpp.ir.implementation.EdgeKind
private import internal.IRBlockImports as Imports
import Imports::EdgeKind
private import Cached
/**
@@ -19,7 +20,7 @@ class IRBlockBase extends TIRBlock {
result = getFirstInstruction(this).toString()
}
final Location getLocation() {
final Language::Location getLocation() {
result = getFirstInstruction().getLocation()
}
@@ -67,7 +68,7 @@ class IRBlockBase extends TIRBlock {
result = getFirstInstruction(this).getEnclosingIRFunction()
}
final Function getEnclosingFunction() {
final Language::Function getEnclosingFunction() {
result = getFirstInstruction(this).getEnclosingFunction()
}
}

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.implementation.EdgeKind as EdgeKind

View File

@@ -1,9 +1,8 @@
private import internal.IRInternal
import Instruction
import cpp
private newtype TIRFunction =
MkIRFunction(Function func) {
MkIRFunction(Language::Function func) {
Construction::functionHasIR(func)
}
@@ -11,7 +10,7 @@ private newtype TIRFunction =
* Represents the IR for a function.
*/
class IRFunction extends TIRFunction {
Function func;
Language::Function func;
IRFunction() {
this = MkIRFunction(func)
@@ -24,14 +23,14 @@ class IRFunction extends TIRFunction {
/**
* Gets the function whose IR is represented.
*/
final Function getFunction() {
final Language::Function getFunction() {
result = func
}
/**
* Gets the location of the function.
*/
final Location getLocation() {
final Language::Location getLocation() {
result = func.getLocation()
}

View File

@@ -1,12 +1,12 @@
private import internal.IRInternal
import IRFunction
import cpp
import semmle.code.cpp.ir.implementation.TempVariableTag
private import semmle.code.cpp.ir.internal.IRUtilities
private import semmle.code.cpp.ir.internal.TempVariableTag
private import semmle.code.cpp.ir.internal.TIRVariable
private import internal.IRVariableImports as Imports
import Imports::TempVariableTag
private import Imports::IRUtilities
private import Imports::TTempVariableTag
private import Imports::TIRVariable
IRUserVariable getIRUserVariable(Function func, Variable var) {
IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var) {
result.getVariable() = var and
result.getEnclosingFunction() = func
}
@@ -17,20 +17,20 @@ IRUserVariable getIRUserVariable(Function func, Variable var) {
* generated by the AST-to-IR translation (`IRTempVariable`).
*/
abstract class IRVariable extends TIRVariable {
Function func;
Language::Function func;
abstract string toString();
/**
* Gets the type of the variable.
*/
abstract Type getType();
abstract Language::Type getType();
/**
* Gets the AST node that declared this variable, or that introduced this
* variable as part of the AST-to-IR translation.
*/
abstract Locatable getAST();
abstract Language::AST getAST();
/**
* Gets an identifier string for the variable. This identifier is unique
@@ -41,7 +41,7 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the source location of this variable.
*/
final Location getLocation() {
final Language::Location getLocation() {
result = getAST().getLocation()
}
@@ -55,7 +55,7 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the function that references this variable.
*/
final Function getEnclosingFunction() {
final Language::Function getEnclosingFunction() {
result = func
}
}
@@ -63,29 +63,34 @@ abstract class IRVariable extends TIRVariable {
/**
* Represents a user-declared variable referenced by the IR for a function.
*/
abstract class IRUserVariable extends IRVariable {
Variable var;
class IRUserVariable extends IRVariable, TIRUserVariable {
Language::Variable var;
Language::Type type;
IRUserVariable() {
this = TIRUserVariable(var, type, func)
}
override final string toString() {
result = var.toString()
result = getVariable().toString()
}
override final Type getType() {
result = getVariableType(var)
}
override final Locatable getAST() {
override final Language::AST getAST() {
result = var
}
override final string getUniqueId() {
result = var.toString() + " " + var.getLocation().toString()
result = getVariable().toString() + " " + getVariable().getLocation().toString()
}
override final Language::Type getType() {
result = type
}
/**
* Gets the original user-declared variable.
*/
final Variable getVariable() {
Language::Variable getVariable() {
result = var
}
}
@@ -98,45 +103,49 @@ abstract class IRUserVariable extends IRVariable {
abstract class IRAutomaticVariable extends IRVariable {
}
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable,
TIRAutomaticUserVariable {
LocalScopeVariable localVar;
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
IRAutomaticUserVariable() {
this = TIRAutomaticUserVariable(localVar, func) and
var = localVar
Language::isVariableAutomatic(var)
}
final LocalScopeVariable getLocalVariable() {
result = localVar
final override Language::AutomaticVariable getVariable() {
result = var
}
}
class IRStaticUserVariable extends IRUserVariable, TIRStaticUserVariable {
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
IRStaticUserVariable() {
this = TIRStaticUserVariable(var, func)
not Language::isVariableAutomatic(var)
}
final override Language::StaticVariable getVariable() {
result = var
}
}
IRTempVariable getIRTempVariable(Locatable ast, TempVariableTag tag) {
IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getAST() = ast and
result.getTag() = tag
}
class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
Locatable ast;
Language::AST ast;
TempVariableTag tag;
Type type;
Language::Type type;
IRTempVariable() {
this = TIRTempVariable(func, ast, tag, type)
}
override final Type getType() {
override final Language::Type getType() {
result = type
}
override final Locatable getAST() {
override final Language::AST getAST() {
result = ast
}

View File

@@ -3,13 +3,11 @@ import IRFunction
import IRBlock
import IRVariable
import Operand
import cpp
import semmle.code.cpp.ir.implementation.EdgeKind
import semmle.code.cpp.ir.implementation.MemoryAccessKind
import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.Print
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import internal.InstructionImports as Imports
import Imports::EdgeKind
import Imports::MemoryAccessKind
import Imports::Opcode
private import Imports::OperandTag
module InstructionSanity {
/**
@@ -60,7 +58,7 @@ module InstructionSanity {
message = "Instruction '" + instr.getOpcode().toString() + "' is missing an expected operand with tag '" +
tag.toString() + "' in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = getIdentityString(func.getFunction())
funcText = Language::getIdentityString(func.getFunction())
)
}
@@ -101,10 +99,10 @@ module InstructionSanity {
}
query predicate missingOperandType(Operand operand, string message) {
exists(Function func |
exists(Language::Function func |
not exists(operand.getType()) and
func = operand.getUse().getEnclosingFunction() and
message = "Operand missing type in function '" + getIdentityString(func) + "'."
message = "Operand missing type in function '" + Language::getIdentityString(func) + "'."
)
}
@@ -135,14 +133,13 @@ module InstructionSanity {
* Holds if `instr` in `f` is part of a loop even though the AST of `f`
* contains no element that can cause loops.
*/
query predicate unexplainedLoop(Function f, Instruction instr) {
query predicate unexplainedLoop(Language::Function f, Instruction instr) {
exists(IRBlock block |
instr.getBlock() = block and
block.getEnclosingFunction() = f and
block.getASuccessor+() = block
) and
not exists(Loop l | l.getEnclosingFunction() = f) and
not exists(GotoStmt s | s.getEnclosingFunction() = f)
not Language::hasPotentialLoop(f)
}
/**
@@ -201,7 +198,7 @@ module InstructionSanity {
entry = f.getEntryBlock() and
entry.getASuccessor+() = block and
not forwardEdge+(entry, block) and
not exists(GotoStmt s | s.getEnclosingFunction() = f.getFunction())
not Language::hasGoto(f.getFunction())
)
}
@@ -209,7 +206,7 @@ module InstructionSanity {
* Holds if the number of back edges differs between the `Instruction` graph
* and the `IRBlock` graph.
*/
query predicate backEdgeCountMismatch(Function f, int fromInstr, int fromBlock) {
query predicate backEdgeCountMismatch(Language::Function f, int fromInstr, int fromBlock) {
fromInstr = count(Instruction i1, Instruction i2 |
i1.getEnclosingFunction() = f and i1.getBackEdgeSuccessor(_) = i2
) and
@@ -266,7 +263,7 @@ class Instruction extends Construction::TInstruction {
}
private string getResultPrefix() {
if getResultType() instanceof VoidType then
if getResultType() instanceof Language::VoidType then
result = "v"
else if hasMemoryResult() then
if isResultModeled() then
@@ -312,7 +309,7 @@ class Instruction extends Construction::TInstruction {
string getResultTypeString() {
exists(string valcat |
valcat = getValueCategoryString(getResultType().toString()) and
if (getResultType() instanceof UnknownType and
if (getResultType() instanceof Language::UnknownType and
not isGLValue() and
exists(getResultSize())) then (
result = valcat + "[" + getResultSize().toString() + "]"
@@ -379,7 +376,7 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the function that contains this instruction.
*/
final Function getEnclosingFunction() {
final Language::Function getEnclosingFunction() {
result = getEnclosingIRFunction().getFunction()
}
@@ -393,28 +390,28 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the AST that caused this instruction to be generated.
*/
final Locatable getAST() {
final Language::AST getAST() {
result = Construction::getInstructionAST(this)
}
/**
* Gets the location of the source code for this instruction.
*/
final Location getLocation() {
final Language::Location getLocation() {
result = getAST().getLocation()
}
/**
* Gets the `Expr` whose result is computed by this instruction, if any.
*/
final Expr getConvertedResultExpression() {
final Language::Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the unconverted `Expr` whose result is computed by this instruction, if any.
*/
final Expr getUnconvertedResultExpression() {
final Language::Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)
}
@@ -425,7 +422,7 @@ class Instruction extends Construction::TInstruction {
* If `isGLValue()` holds, then the result type of this instruction should be
* thought of as "pointer to `getResultType()`".
*/
final Type getResultType() {
final Language::Type getResultType() {
Construction::instructionHasType(this, result, _)
}
@@ -461,11 +458,9 @@ class Instruction extends Construction::TInstruction {
final int getResultSize() {
if isGLValue() then (
// a glvalue is always pointer-sized.
exists(NullPointerType nullptr |
result = nullptr.getSize()
)
result = Language::getPointerSize()
)
else if getResultType() instanceof UnknownType then
else if getResultType() instanceof Language::UnknownType then
result = Construction::getInstructionResultSize(this)
else (
result = getResultType().getSize()
@@ -616,7 +611,7 @@ class VariableInstruction extends Instruction {
}
class FieldInstruction extends Instruction {
Field field;
Language::Field field;
FieldInstruction() {
field = Construction::getInstructionField(this)
@@ -626,13 +621,13 @@ class FieldInstruction extends Instruction {
result = field.toString()
}
final Field getField() {
final Language::Field getField() {
result = field
}
}
class FunctionInstruction extends Instruction {
Function funcSymbol;
Language::Function funcSymbol;
FunctionInstruction() {
funcSymbol = Construction::getInstructionFunction(this)
@@ -642,7 +637,7 @@ class FunctionInstruction extends Instruction {
result = funcSymbol.toString()
}
final Function getFunctionSymbol() {
final Language::Function getFunctionSymbol() {
result = funcSymbol
}
}
@@ -680,7 +675,7 @@ class InitializeParameterInstruction extends VariableInstruction {
getOpcode() instanceof Opcode::InitializeParameter
}
final Parameter getParameter() {
final Language::Parameter getParameter() {
result = var.(IRUserVariable).getVariable()
}
@@ -738,9 +733,9 @@ class UninitializedInstruction extends VariableInstruction {
}
/**
* Gets the `LocalVariable` that is uninitialized.
* Gets the variable that is uninitialized.
*/
final LocalVariable getLocalVariable() {
final Language::Variable getLocalVariable() {
result = var.(IRUserVariable).getVariable()
}
}
@@ -877,28 +872,28 @@ class ConstantInstruction extends ConstantValueInstruction {
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
getResultType() instanceof IntegralType
getResultType() instanceof Language::IntegralType
}
}
class FloatConstantInstruction extends ConstantInstruction {
FloatConstantInstruction() {
getResultType() instanceof FloatingPointType
getResultType() instanceof Language::FloatingPointType
}
}
class StringConstantInstruction extends Instruction {
StringLiteral value;
Language::StringLiteral value;
StringConstantInstruction() {
value = Construction::getInstructionStringLiteral(this)
}
override final string getImmediateString() {
result = value.getValueText().replaceAll("\n", " ").replaceAll("\r", "").replaceAll("\t", " ")
result = Language::getStringLiteralText(value)
}
final StringLiteral getValue() {
final Language::StringLiteral getValue() {
result = value
}
}
@@ -1086,8 +1081,8 @@ class ConvertInstruction extends UnaryInstruction {
* related by inheritance.
*/
class InheritanceConversionInstruction extends UnaryInstruction {
Class baseClass;
Class derivedClass;
Language::Class baseClass;
Language::Class derivedClass;
InheritanceConversionInstruction() {
Construction::getInstructionInheritance(this, baseClass, derivedClass)
@@ -1102,7 +1097,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* the base and derived classes. This predicate does not hold if the
* conversion is to an indirect virtual base class.
*/
final ClassDerivation getDerivation() {
final Language::ClassDerivation getDerivation() {
result.getBaseClass() = baseClass and result.getDerivedClass() = derivedClass
}
@@ -1111,14 +1106,14 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* base class of the derived class, or a virtual base class of the
* derived class.
*/
final Class getBaseClass() {
final Language::Class getBaseClass() {
result = baseClass
}
/**
* Gets the derived class of the conversion.
*/
final Class getDerivedClass() {
final Language::Class getDerivedClass() {
result = derivedClass
}
}
@@ -1349,7 +1344,7 @@ class CallInstruction extends Instruction {
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
final Function getStaticCallTarget() {
final Language::Function getStaticCallTarget() {
result = getCallTarget().(FunctionInstruction).getFunctionSymbol()
}
@@ -1591,7 +1586,7 @@ class CatchInstruction extends Instruction {
* An instruction that catches an exception of a specific type.
*/
class CatchByTypeInstruction extends CatchInstruction {
Type exceptionType;
Language::Type exceptionType;
CatchByTypeInstruction() {
getOpcode() instanceof Opcode::CatchByType and
@@ -1605,7 +1600,7 @@ class CatchByTypeInstruction extends CatchInstruction {
/**
* Gets the type of exception to be caught.
*/
final Type getExceptionType() {
final Language::Type getExceptionType() {
result = exceptionType
}
}

View File

@@ -1,10 +1,10 @@
private import internal.IRInternal
import Instruction
import IRBlock
import cpp
import semmle.code.cpp.ir.implementation.MemoryAccessKind
import semmle.code.cpp.ir.internal.Overlap
private import semmle.code.cpp.ir.internal.OperandTag
private import internal.OperandImports as Imports
import Imports::MemoryAccessKind
import Imports::Overlap
private import Imports::OperandTag
cached
private newtype TOperand =
@@ -50,7 +50,7 @@ class Operand extends TOperand {
result = "Operand"
}
final Location getLocation() {
final Language::Location getLocation() {
result = getUse().getLocation()
}
@@ -166,7 +166,7 @@ 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.
*/
Type getType() {
Language::Type getType() {
result = getAnyDef().getResultType()
}
@@ -284,7 +284,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
class TypedOperand extends NonPhiMemoryOperand {
override TypedOperandTag tag;
override final Type getType() {
override final Language::Type getType() {
result = Construction::getInstructionOperandType(useInstr, tag)
}
}
@@ -447,7 +447,7 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override final int getSize() {
if getType() instanceof UnknownType then
if getType() instanceof Language::UnknownType then
result = Construction::getInstructionOperandSize(useInstr, tag)
else
result = getType().getSize()

View File

@@ -1,7 +1,7 @@
private import internal.IRInternal
private import IR
import cpp
import semmle.code.cpp.ir.IRConfiguration
private import semmle.code.cpp.Print
private import internal.PrintIRImports as Imports
import Imports::IRConfiguration
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
@@ -17,12 +17,12 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
* Holds if the IR for `func` should be printed. By default, holds for all
* functions.
*/
predicate shouldPrintFunction(Function func) {
predicate shouldPrintFunction(Language::Function func) {
any()
}
}
private predicate shouldPrintFunction(Function func) {
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config |
config.shouldPrintFunction(func)
)
@@ -32,7 +32,7 @@ private predicate shouldPrintFunction(Function func) {
* Override of `IRConfiguration` to only create IR for the functions that are to be dumped.
*/
private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldCreateIRForFunction(Function func) {
override predicate shouldCreateIRForFunction(Language::Function func) {
shouldPrintFunction(func)
}
}
@@ -69,7 +69,7 @@ abstract class PrintableIRNode extends TPrintableIRNode {
/**
* Gets the location to be emitted for the node.
*/
abstract Location getLocation();
abstract Language::Location getLocation();
/**
* Gets the label to be emitted for the node.
@@ -126,16 +126,16 @@ class PrintableIRFunction extends PrintableIRNode, TPrintableIRFunction {
result = irFunc.toString()
}
override Location getLocation() {
override Language::Location getLocation() {
result = irFunc.getLocation()
}
override string getLabel() {
result = getIdentityString(irFunc.getFunction())
result = Language::getIdentityString(irFunc.getFunction())
}
override int getOrder() {
this = rank[result + 1](PrintableIRFunction orderedFunc, Location location |
this = rank[result + 1](PrintableIRFunction orderedFunc, Language::Location location |
location = orderedFunc.getIRFunction().getLocation() |
orderedFunc order by location.getFile().getAbsolutePath(), location.getStartLine(),
location.getStartColumn(), orderedFunc.getLabel()
@@ -165,7 +165,7 @@ class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
result = getLabel()
}
override Location getLocation() {
override Language::Location getLocation() {
result = block.getLocation()
}
@@ -213,7 +213,7 @@ class PrintableInstruction extends PrintableIRNode, TPrintableInstruction {
result = instr.toString()
}
override Location getLocation() {
override Language::Location getLocation() {
result = instr.getLocation()
}

View File

@@ -1,5 +1,5 @@
private import internal.ValueNumberingInternal
import cpp
private import cpp
private import IR
/**

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.implementation.EdgeKind as EdgeKind

View File

@@ -1,6 +1,6 @@
import cpp
private import cpp
import semmle.code.cpp.ir.implementation.raw.IR
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.TempVariableTag
private import InstructionTag
private import TranslatedCondition
@@ -28,6 +28,10 @@ cached private module Cached {
element.hasInstruction(_, tag, _, _)
}
cached predicate hasUserVariable(Function func, Variable var, Type type) {
getTranslatedFunction(func).hasUserVariable(var, type)
}
cached predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag,
Type type) {
exists(TranslatedElement element |

View File

@@ -0,0 +1,2 @@
import semmle.code.cpp.ir.implementation.EdgeKind as EdgeKind
import semmle.code.cpp.ir.implementation.MemoryAccessKind as MemoryAccessKind

View File

@@ -1 +1,2 @@
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
import IRConstruction as Construction

View File

@@ -0,0 +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

View File

@@ -0,0 +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

View File

@@ -1,4 +1,4 @@
import cpp
private import cpp
private predicate fieldIsInitialized(Field field) {
exists(ClassAggregateLiteral initList |

View File

@@ -0,0 +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

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.IRConfiguration as IRConfiguration

View File

@@ -1,6 +1,6 @@
import cpp
private import cpp
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.models.interfaces.SideEffect
private import InstructionTag
private import TranslatedElement

View File

@@ -1,6 +1,6 @@
import cpp
private import cpp
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import InstructionTag
private import TranslatedElement
private import TranslatedExpr

View File

@@ -1,7 +1,7 @@
import cpp
private import cpp
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.IRUtilities
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import InstructionTag
private import TranslatedElement
private import TranslatedExpr

View File

@@ -1,9 +1,8 @@
import cpp
import cpp
private import cpp
import semmle.code.cpp.ir.implementation.raw.IR
private import semmle.code.cpp.ir.IRConfiguration
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.TempVariableTag
private import InstructionTag
private import TranslatedCondition

View File

@@ -1,6 +1,6 @@
import cpp
private import cpp
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.TempVariableTag
private import InstructionTag
private import TranslatedCondition

View File

@@ -1,8 +1,8 @@
import cpp
private import cpp
import semmle.code.cpp.ir.implementation.raw.IR
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.IRUtilities
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.TempVariableTag
private import InstructionTag
private import TranslatedElement
@@ -310,6 +310,29 @@ class TranslatedFunction extends TranslatedElement,
)
}
/**
* Holds if this function defines or accesses variable `var` with type `type`. This includes all
* parameters and local variables, plus any global variables or static data members that are
* directly accessed by the function.
*/
final predicate hasUserVariable(Variable var, Type type) {
(
(
(
var instanceof GlobalOrNamespaceVariable or
var instanceof MemberVariable and not var instanceof Field
) and
exists(VariableAccess access |
access.getTarget() = var and
access.getEnclosingFunction() = func
)
) or
var.(LocalScopeVariable).getFunction() = func or
var.(Parameter).getCatchBlock().getEnclosingFunction() = func
) and
type = getVariableType(var)
}
private final Type getReturnType() {
result = func.getUnspecifiedType()
}

View File

@@ -1,6 +1,6 @@
import cpp
private import cpp
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import InstructionTag
private import TranslatedElement
private import TranslatedExpr

View File

@@ -1,6 +1,7 @@
import cpp
private import cpp
private import semmle.code.cpp.ir.internal.IRUtilities
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.TempVariableTag
private import semmle.code.cpp.ir.internal.OperandTag
private import InstructionTag
private import TranslatedCondition
private import TranslatedDeclarationEntry
@@ -760,6 +761,14 @@ class TranslatedJumpStmt extends TranslatedStmt {
}
}
private EdgeKind getCaseEdge(SwitchCase switchCase) {
exists(CaseEdge edge |
result = edge and
hasCaseEdge(switchCase, edge.getMinValue(), edge.getMaxValue())
) or
(switchCase instanceof DefaultCase and result instanceof DefaultEdge)
}
class TranslatedSwitchStmt extends TranslatedStmt {
override SwitchStmt stmt;

View File

@@ -3,8 +3,9 @@ import Instruction
import IRBlock
import IRVariable
import Operand
import semmle.code.cpp.ir.implementation.EdgeKind
import semmle.code.cpp.ir.implementation.MemoryAccessKind
private import internal.IRImports as Imports
import Imports::EdgeKind
import Imports::MemoryAccessKind
private newtype TIRPropertyProvider = MkIRPropertyProvider()

View File

@@ -1,6 +1,7 @@
private import internal.IRInternal
import Instruction
import semmle.code.cpp.ir.implementation.EdgeKind
private import internal.IRBlockImports as Imports
import Imports::EdgeKind
private import Cached
/**
@@ -19,7 +20,7 @@ class IRBlockBase extends TIRBlock {
result = getFirstInstruction(this).toString()
}
final Location getLocation() {
final Language::Location getLocation() {
result = getFirstInstruction().getLocation()
}
@@ -67,7 +68,7 @@ class IRBlockBase extends TIRBlock {
result = getFirstInstruction(this).getEnclosingIRFunction()
}
final Function getEnclosingFunction() {
final Language::Function getEnclosingFunction() {
result = getFirstInstruction(this).getEnclosingFunction()
}
}

View File

@@ -1,9 +1,8 @@
private import internal.IRInternal
import Instruction
import cpp
private newtype TIRFunction =
MkIRFunction(Function func) {
MkIRFunction(Language::Function func) {
Construction::functionHasIR(func)
}
@@ -11,7 +10,7 @@ private newtype TIRFunction =
* Represents the IR for a function.
*/
class IRFunction extends TIRFunction {
Function func;
Language::Function func;
IRFunction() {
this = MkIRFunction(func)
@@ -24,14 +23,14 @@ class IRFunction extends TIRFunction {
/**
* Gets the function whose IR is represented.
*/
final Function getFunction() {
final Language::Function getFunction() {
result = func
}
/**
* Gets the location of the function.
*/
final Location getLocation() {
final Language::Location getLocation() {
result = func.getLocation()
}

View File

@@ -1,12 +1,12 @@
private import internal.IRInternal
import IRFunction
import cpp
import semmle.code.cpp.ir.implementation.TempVariableTag
private import semmle.code.cpp.ir.internal.IRUtilities
private import semmle.code.cpp.ir.internal.TempVariableTag
private import semmle.code.cpp.ir.internal.TIRVariable
private import internal.IRVariableImports as Imports
import Imports::TempVariableTag
private import Imports::IRUtilities
private import Imports::TTempVariableTag
private import Imports::TIRVariable
IRUserVariable getIRUserVariable(Function func, Variable var) {
IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var) {
result.getVariable() = var and
result.getEnclosingFunction() = func
}
@@ -17,20 +17,20 @@ IRUserVariable getIRUserVariable(Function func, Variable var) {
* generated by the AST-to-IR translation (`IRTempVariable`).
*/
abstract class IRVariable extends TIRVariable {
Function func;
Language::Function func;
abstract string toString();
/**
* Gets the type of the variable.
*/
abstract Type getType();
abstract Language::Type getType();
/**
* Gets the AST node that declared this variable, or that introduced this
* variable as part of the AST-to-IR translation.
*/
abstract Locatable getAST();
abstract Language::AST getAST();
/**
* Gets an identifier string for the variable. This identifier is unique
@@ -41,7 +41,7 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the source location of this variable.
*/
final Location getLocation() {
final Language::Location getLocation() {
result = getAST().getLocation()
}
@@ -55,7 +55,7 @@ abstract class IRVariable extends TIRVariable {
/**
* Gets the function that references this variable.
*/
final Function getEnclosingFunction() {
final Language::Function getEnclosingFunction() {
result = func
}
}
@@ -63,29 +63,34 @@ abstract class IRVariable extends TIRVariable {
/**
* Represents a user-declared variable referenced by the IR for a function.
*/
abstract class IRUserVariable extends IRVariable {
Variable var;
class IRUserVariable extends IRVariable, TIRUserVariable {
Language::Variable var;
Language::Type type;
IRUserVariable() {
this = TIRUserVariable(var, type, func)
}
override final string toString() {
result = var.toString()
result = getVariable().toString()
}
override final Type getType() {
result = getVariableType(var)
}
override final Locatable getAST() {
override final Language::AST getAST() {
result = var
}
override final string getUniqueId() {
result = var.toString() + " " + var.getLocation().toString()
result = getVariable().toString() + " " + getVariable().getLocation().toString()
}
override final Language::Type getType() {
result = type
}
/**
* Gets the original user-declared variable.
*/
final Variable getVariable() {
Language::Variable getVariable() {
result = var
}
}
@@ -98,45 +103,49 @@ abstract class IRUserVariable extends IRVariable {
abstract class IRAutomaticVariable extends IRVariable {
}
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable,
TIRAutomaticUserVariable {
LocalScopeVariable localVar;
class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable {
override Language::AutomaticVariable var;
IRAutomaticUserVariable() {
this = TIRAutomaticUserVariable(localVar, func) and
var = localVar
Language::isVariableAutomatic(var)
}
final LocalScopeVariable getLocalVariable() {
result = localVar
final override Language::AutomaticVariable getVariable() {
result = var
}
}
class IRStaticUserVariable extends IRUserVariable, TIRStaticUserVariable {
class IRStaticUserVariable extends IRUserVariable {
override Language::StaticVariable var;
IRStaticUserVariable() {
this = TIRStaticUserVariable(var, func)
not Language::isVariableAutomatic(var)
}
final override Language::StaticVariable getVariable() {
result = var
}
}
IRTempVariable getIRTempVariable(Locatable ast, TempVariableTag tag) {
IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) {
result.getAST() = ast and
result.getTag() = tag
}
class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
Locatable ast;
Language::AST ast;
TempVariableTag tag;
Type type;
Language::Type type;
IRTempVariable() {
this = TIRTempVariable(func, ast, tag, type)
}
override final Type getType() {
override final Language::Type getType() {
result = type
}
override final Locatable getAST() {
override final Language::AST getAST() {
result = ast
}

View File

@@ -3,13 +3,11 @@ import IRFunction
import IRBlock
import IRVariable
import Operand
import cpp
import semmle.code.cpp.ir.implementation.EdgeKind
import semmle.code.cpp.ir.implementation.MemoryAccessKind
import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.Print
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import internal.InstructionImports as Imports
import Imports::EdgeKind
import Imports::MemoryAccessKind
import Imports::Opcode
private import Imports::OperandTag
module InstructionSanity {
/**
@@ -60,7 +58,7 @@ module InstructionSanity {
message = "Instruction '" + instr.getOpcode().toString() + "' is missing an expected operand with tag '" +
tag.toString() + "' in function '$@'." and
func = instr.getEnclosingIRFunction() and
funcText = getIdentityString(func.getFunction())
funcText = Language::getIdentityString(func.getFunction())
)
}
@@ -101,10 +99,10 @@ module InstructionSanity {
}
query predicate missingOperandType(Operand operand, string message) {
exists(Function func |
exists(Language::Function func |
not exists(operand.getType()) and
func = operand.getUse().getEnclosingFunction() and
message = "Operand missing type in function '" + getIdentityString(func) + "'."
message = "Operand missing type in function '" + Language::getIdentityString(func) + "'."
)
}
@@ -135,14 +133,13 @@ module InstructionSanity {
* Holds if `instr` in `f` is part of a loop even though the AST of `f`
* contains no element that can cause loops.
*/
query predicate unexplainedLoop(Function f, Instruction instr) {
query predicate unexplainedLoop(Language::Function f, Instruction instr) {
exists(IRBlock block |
instr.getBlock() = block and
block.getEnclosingFunction() = f and
block.getASuccessor+() = block
) and
not exists(Loop l | l.getEnclosingFunction() = f) and
not exists(GotoStmt s | s.getEnclosingFunction() = f)
not Language::hasPotentialLoop(f)
}
/**
@@ -201,7 +198,7 @@ module InstructionSanity {
entry = f.getEntryBlock() and
entry.getASuccessor+() = block and
not forwardEdge+(entry, block) and
not exists(GotoStmt s | s.getEnclosingFunction() = f.getFunction())
not Language::hasGoto(f.getFunction())
)
}
@@ -209,7 +206,7 @@ module InstructionSanity {
* Holds if the number of back edges differs between the `Instruction` graph
* and the `IRBlock` graph.
*/
query predicate backEdgeCountMismatch(Function f, int fromInstr, int fromBlock) {
query predicate backEdgeCountMismatch(Language::Function f, int fromInstr, int fromBlock) {
fromInstr = count(Instruction i1, Instruction i2 |
i1.getEnclosingFunction() = f and i1.getBackEdgeSuccessor(_) = i2
) and
@@ -266,7 +263,7 @@ class Instruction extends Construction::TInstruction {
}
private string getResultPrefix() {
if getResultType() instanceof VoidType then
if getResultType() instanceof Language::VoidType then
result = "v"
else if hasMemoryResult() then
if isResultModeled() then
@@ -312,7 +309,7 @@ class Instruction extends Construction::TInstruction {
string getResultTypeString() {
exists(string valcat |
valcat = getValueCategoryString(getResultType().toString()) and
if (getResultType() instanceof UnknownType and
if (getResultType() instanceof Language::UnknownType and
not isGLValue() and
exists(getResultSize())) then (
result = valcat + "[" + getResultSize().toString() + "]"
@@ -379,7 +376,7 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the function that contains this instruction.
*/
final Function getEnclosingFunction() {
final Language::Function getEnclosingFunction() {
result = getEnclosingIRFunction().getFunction()
}
@@ -393,28 +390,28 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the AST that caused this instruction to be generated.
*/
final Locatable getAST() {
final Language::AST getAST() {
result = Construction::getInstructionAST(this)
}
/**
* Gets the location of the source code for this instruction.
*/
final Location getLocation() {
final Language::Location getLocation() {
result = getAST().getLocation()
}
/**
* Gets the `Expr` whose result is computed by this instruction, if any.
*/
final Expr getConvertedResultExpression() {
final Language::Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the unconverted `Expr` whose result is computed by this instruction, if any.
*/
final Expr getUnconvertedResultExpression() {
final Language::Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)
}
@@ -425,7 +422,7 @@ class Instruction extends Construction::TInstruction {
* If `isGLValue()` holds, then the result type of this instruction should be
* thought of as "pointer to `getResultType()`".
*/
final Type getResultType() {
final Language::Type getResultType() {
Construction::instructionHasType(this, result, _)
}
@@ -461,11 +458,9 @@ class Instruction extends Construction::TInstruction {
final int getResultSize() {
if isGLValue() then (
// a glvalue is always pointer-sized.
exists(NullPointerType nullptr |
result = nullptr.getSize()
)
result = Language::getPointerSize()
)
else if getResultType() instanceof UnknownType then
else if getResultType() instanceof Language::UnknownType then
result = Construction::getInstructionResultSize(this)
else (
result = getResultType().getSize()
@@ -616,7 +611,7 @@ class VariableInstruction extends Instruction {
}
class FieldInstruction extends Instruction {
Field field;
Language::Field field;
FieldInstruction() {
field = Construction::getInstructionField(this)
@@ -626,13 +621,13 @@ class FieldInstruction extends Instruction {
result = field.toString()
}
final Field getField() {
final Language::Field getField() {
result = field
}
}
class FunctionInstruction extends Instruction {
Function funcSymbol;
Language::Function funcSymbol;
FunctionInstruction() {
funcSymbol = Construction::getInstructionFunction(this)
@@ -642,7 +637,7 @@ class FunctionInstruction extends Instruction {
result = funcSymbol.toString()
}
final Function getFunctionSymbol() {
final Language::Function getFunctionSymbol() {
result = funcSymbol
}
}
@@ -680,7 +675,7 @@ class InitializeParameterInstruction extends VariableInstruction {
getOpcode() instanceof Opcode::InitializeParameter
}
final Parameter getParameter() {
final Language::Parameter getParameter() {
result = var.(IRUserVariable).getVariable()
}
@@ -738,9 +733,9 @@ class UninitializedInstruction extends VariableInstruction {
}
/**
* Gets the `LocalVariable` that is uninitialized.
* Gets the variable that is uninitialized.
*/
final LocalVariable getLocalVariable() {
final Language::Variable getLocalVariable() {
result = var.(IRUserVariable).getVariable()
}
}
@@ -877,28 +872,28 @@ class ConstantInstruction extends ConstantValueInstruction {
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
getResultType() instanceof IntegralType
getResultType() instanceof Language::IntegralType
}
}
class FloatConstantInstruction extends ConstantInstruction {
FloatConstantInstruction() {
getResultType() instanceof FloatingPointType
getResultType() instanceof Language::FloatingPointType
}
}
class StringConstantInstruction extends Instruction {
StringLiteral value;
Language::StringLiteral value;
StringConstantInstruction() {
value = Construction::getInstructionStringLiteral(this)
}
override final string getImmediateString() {
result = value.getValueText().replaceAll("\n", " ").replaceAll("\r", "").replaceAll("\t", " ")
result = Language::getStringLiteralText(value)
}
final StringLiteral getValue() {
final Language::StringLiteral getValue() {
result = value
}
}
@@ -1086,8 +1081,8 @@ class ConvertInstruction extends UnaryInstruction {
* related by inheritance.
*/
class InheritanceConversionInstruction extends UnaryInstruction {
Class baseClass;
Class derivedClass;
Language::Class baseClass;
Language::Class derivedClass;
InheritanceConversionInstruction() {
Construction::getInstructionInheritance(this, baseClass, derivedClass)
@@ -1102,7 +1097,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* the base and derived classes. This predicate does not hold if the
* conversion is to an indirect virtual base class.
*/
final ClassDerivation getDerivation() {
final Language::ClassDerivation getDerivation() {
result.getBaseClass() = baseClass and result.getDerivedClass() = derivedClass
}
@@ -1111,14 +1106,14 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* base class of the derived class, or a virtual base class of the
* derived class.
*/
final Class getBaseClass() {
final Language::Class getBaseClass() {
result = baseClass
}
/**
* Gets the derived class of the conversion.
*/
final Class getDerivedClass() {
final Language::Class getDerivedClass() {
result = derivedClass
}
}
@@ -1349,7 +1344,7 @@ class CallInstruction extends Instruction {
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
final Function getStaticCallTarget() {
final Language::Function getStaticCallTarget() {
result = getCallTarget().(FunctionInstruction).getFunctionSymbol()
}
@@ -1591,7 +1586,7 @@ class CatchInstruction extends Instruction {
* An instruction that catches an exception of a specific type.
*/
class CatchByTypeInstruction extends CatchInstruction {
Type exceptionType;
Language::Type exceptionType;
CatchByTypeInstruction() {
getOpcode() instanceof Opcode::CatchByType and
@@ -1605,7 +1600,7 @@ class CatchByTypeInstruction extends CatchInstruction {
/**
* Gets the type of exception to be caught.
*/
final Type getExceptionType() {
final Language::Type getExceptionType() {
result = exceptionType
}
}

View File

@@ -1,10 +1,10 @@
private import internal.IRInternal
import Instruction
import IRBlock
import cpp
import semmle.code.cpp.ir.implementation.MemoryAccessKind
import semmle.code.cpp.ir.internal.Overlap
private import semmle.code.cpp.ir.internal.OperandTag
private import internal.OperandImports as Imports
import Imports::MemoryAccessKind
import Imports::Overlap
private import Imports::OperandTag
cached
private newtype TOperand =
@@ -50,7 +50,7 @@ class Operand extends TOperand {
result = "Operand"
}
final Location getLocation() {
final Language::Location getLocation() {
result = getUse().getLocation()
}
@@ -166,7 +166,7 @@ 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.
*/
Type getType() {
Language::Type getType() {
result = getAnyDef().getResultType()
}
@@ -284,7 +284,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
class TypedOperand extends NonPhiMemoryOperand {
override TypedOperandTag tag;
override final Type getType() {
override final Language::Type getType() {
result = Construction::getInstructionOperandType(useInstr, tag)
}
}
@@ -447,7 +447,7 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override final int getSize() {
if getType() instanceof UnknownType then
if getType() instanceof Language::UnknownType then
result = Construction::getInstructionOperandSize(useInstr, tag)
else
result = getType().getSize()

View File

@@ -1,7 +1,7 @@
private import internal.IRInternal
private import IR
import cpp
import semmle.code.cpp.ir.IRConfiguration
private import semmle.code.cpp.Print
private import internal.PrintIRImports as Imports
import Imports::IRConfiguration
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
@@ -17,12 +17,12 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
* Holds if the IR for `func` should be printed. By default, holds for all
* functions.
*/
predicate shouldPrintFunction(Function func) {
predicate shouldPrintFunction(Language::Function func) {
any()
}
}
private predicate shouldPrintFunction(Function func) {
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config |
config.shouldPrintFunction(func)
)
@@ -32,7 +32,7 @@ private predicate shouldPrintFunction(Function func) {
* Override of `IRConfiguration` to only create IR for the functions that are to be dumped.
*/
private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldCreateIRForFunction(Function func) {
override predicate shouldCreateIRForFunction(Language::Function func) {
shouldPrintFunction(func)
}
}
@@ -69,7 +69,7 @@ abstract class PrintableIRNode extends TPrintableIRNode {
/**
* Gets the location to be emitted for the node.
*/
abstract Location getLocation();
abstract Language::Location getLocation();
/**
* Gets the label to be emitted for the node.
@@ -126,16 +126,16 @@ class PrintableIRFunction extends PrintableIRNode, TPrintableIRFunction {
result = irFunc.toString()
}
override Location getLocation() {
override Language::Location getLocation() {
result = irFunc.getLocation()
}
override string getLabel() {
result = getIdentityString(irFunc.getFunction())
result = Language::getIdentityString(irFunc.getFunction())
}
override int getOrder() {
this = rank[result + 1](PrintableIRFunction orderedFunc, Location location |
this = rank[result + 1](PrintableIRFunction orderedFunc, Language::Location location |
location = orderedFunc.getIRFunction().getLocation() |
orderedFunc order by location.getFile().getAbsolutePath(), location.getStartLine(),
location.getStartColumn(), orderedFunc.getLabel()
@@ -165,7 +165,7 @@ class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
result = getLabel()
}
override Location getLocation() {
override Language::Location getLocation() {
result = block.getLocation()
}
@@ -213,7 +213,7 @@ class PrintableInstruction extends PrintableIRNode, TPrintableInstruction {
result = instr.toString()
}
override Location getLocation() {
override Language::Location getLocation() {
result = instr.getLocation()
}

View File

@@ -1,5 +1,5 @@
private import internal.ValueNumberingInternal
import cpp
private import cpp
private import IR
/**

View File

@@ -1,5 +1,5 @@
private import AliasAnalysisInternal
import cpp
private import cpp
private import InputIR
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.implementation.EdgeKind as EdgeKind

View File

@@ -0,0 +1,2 @@
import semmle.code.cpp.ir.implementation.EdgeKind as EdgeKind
import semmle.code.cpp.ir.implementation.MemoryAccessKind as MemoryAccessKind

View File

@@ -1 +1,2 @@
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
import SSAConstruction as Construction

View File

@@ -0,0 +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

View File

@@ -0,0 +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

View File

@@ -0,0 +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

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.IRConfiguration as IRConfiguration

View File

@@ -1,7 +1,7 @@
import SSAConstructionInternal
import cpp
private import cpp
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.Overlap
private import NewIR

View File

@@ -1,8 +1,8 @@
import AliasAnalysis
import cpp
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.internal.OperandTag
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.Overlap
private class IntValue = Ints::IntValue;

View File

@@ -0,0 +1,75 @@
private import cpp as Cpp
private import semmle.code.cpp.Print as Print
private import IRUtilities
class Function = Cpp::Function;
class Location = Cpp::Location;
class AST = Cpp::Locatable;
class Type = Cpp::Type;
class UnknownType = Cpp::UnknownType;
class VoidType = Cpp::VoidType;
class IntegralType = Cpp::IntegralType;
class FloatingPointType = Cpp::FloatingPointType;
// REVIEW: May need to synthesize this for other languages. Or do we really need it at all?
class ClassDerivation = Cpp::ClassDerivation;
class StringLiteral = Cpp::StringLiteral;
class Variable = Cpp::Variable;
class AutomaticVariable = Cpp::LocalScopeVariable;
class StaticVariable = Cpp::Variable;
class Parameter = Cpp::Parameter;
class Field = Cpp::Field;
// TODO: Remove necessity for these.
class Expr = Cpp::Expr;
class Class = Cpp::Class; // Used for inheritance conversions
predicate getIdentityString = Print::getIdentityString/1;
predicate hasCaseEdge(string minValue, string maxValue) {
exists(Cpp::SwitchCase switchCase |
hasCaseEdge(switchCase, minValue, maxValue)
)
}
predicate hasPositionalArgIndex(int argIndex) {
exists(Cpp::FunctionCall call |
exists(call.getArgument(argIndex))
) or
exists(Cpp::BuiltInOperation op |
exists(op.getChild(argIndex))
)
}
predicate hasAsmOperandIndex(int operandIndex) {
exists(Cpp::AsmStmt asm |
exists(asm.getChild(operandIndex))
)
}
int getPointerSize() {
exists(Cpp::NullPointerType nullptr |
result = nullptr.getSize()
)
}
predicate isVariableAutomatic(Variable var) {
var instanceof Cpp::LocalScopeVariable and
not var.(Cpp::LocalScopeVariable).isStatic()
}
string getStringLiteralText(StringLiteral s) {
result = s.getValueText().replaceAll("\n", " ").replaceAll("\r", "").replaceAll("\t", " ")
}
predicate hasPotentialLoop(Function f) {
exists(Cpp::Loop l | l.getEnclosingFunction() = f) or
exists(Cpp::GotoStmt s | s.getEnclosingFunction() = f)
}
predicate hasGoto(Function f) {
exists(Cpp::GotoStmt s | s.getEnclosingFunction() = f)
}

View File

@@ -1,4 +1,4 @@
import cpp
private import cpp
/**
* Given a type, get the type that would result by applying "pointer decay".
@@ -32,3 +32,11 @@ Type getVariableType(Variable v) {
)
)
}
predicate hasCaseEdge(SwitchCase switchCase, string minValue, string maxValue) {
minValue = switchCase.getExpr().getFullyConverted().getValue() and
if exists(switchCase.getEndExpr()) then
maxValue = switchCase.getEndExpr().getFullyConverted().getValue()
else
maxValue = minValue
}

View File

@@ -1,5 +1,3 @@
import cpp
class IntValue = int;
/**

View File

@@ -1,5 +1,3 @@
import cpp
private newtype TOverlap =
TMayPartiallyOverlap() or
TMustTotallyOverlap() or

View File

@@ -1,25 +0,0 @@
private import cpp
private import semmle.code.cpp.ir.implementation.TempVariableTag
private import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as Construction
newtype TIRVariable =
TIRAutomaticUserVariable(LocalScopeVariable var, Function func) {
Construction::functionHasIR(func) and
var.getFunction() = func or
var.(Parameter).getCatchBlock().getEnclosingFunction() = func
} or
TIRStaticUserVariable(Variable var, Function func) {
Construction::functionHasIR(func) and
(
var instanceof GlobalOrNamespaceVariable or
var instanceof MemberVariable and not var instanceof Field
) and
exists(VariableAccess access |
access.getTarget() = var and
access.getEnclosingFunction() = func
)
} or
TIRTempVariable(Function func, Locatable ast, TempVariableTag tag, Type type) {
Construction::hasTempVariable(func, ast, tag, type)
}

View File

@@ -1,5 +1,3 @@
import cpp
newtype TTempVariableTag =
ConditionValueTempVar() or
ReturnValueTempVar() or