Skip to content
10 changes: 3 additions & 7 deletions cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,7 @@ class ExprNode extends InstructionNode {
* as `x` in `f(x)` and implicit parameters such as `this` in `x.f()`
*/
class ParameterNode extends InstructionNode {
ParameterNode() {
instr instanceof InitializeParameterInstruction
or
instr instanceof InitializeThisInstruction
}
override InitializeParameterInstruction instr;

/**
* Holds if this node is the parameter of `c` at the specified (zero-based)
Expand All @@ -178,7 +174,7 @@ class ParameterNode extends InstructionNode {
* flow graph.
*/
private class ExplicitParameterNode extends ParameterNode {
override InitializeParameterInstruction instr;
ExplicitParameterNode() { exists(instr.getParameter()) }

override predicate isParameterOf(Function f, int i) { f.getParameter(i) = instr.getParameter() }

Expand All @@ -189,7 +185,7 @@ private class ExplicitParameterNode extends ParameterNode {
}

private class ThisParameterNode extends ParameterNode {
override InitializeThisInstruction instr;
ThisParameterNode() { instr.getIRVariable() instanceof IRThisVariable }

override predicate isParameterOf(Function f, int i) {
i = -1 and instr.getEnclosingFunction() = f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ class IREllipsisVariable extends IRTempVariable {
final override string toString() { result = "#ellipsis" }
}

/**
* A temporary variable generated to hold the `this` pointer.
*/
class IRThisVariable extends IRTempVariable {
IRThisVariable() { tag = ThisTempVar() }

final override string toString() { result = "#this" }
}

/**
* A variable generated to represent the contents of a string literal. This variable acts much like
* a read-only global variable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ private predicate isArgumentForParameter(CallInstruction ci, Operand operand, In
init.(InitializeParameterInstruction).getParameter() =
f.getParameter(operand.(PositionalArgumentOperand).getIndex())
or
init instanceof InitializeThisInstruction and
init.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable and
init.getEnclosingFunction() = f and
operand instanceof ThisArgumentOperand
) and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ private import AliasAnalysis

private newtype TAllocation =
TVariableAllocation(IRVariable var) or
TIndirectParameterAllocation(IRAutomaticUserVariable var) {
TIndirectParameterAllocation(IRAutomaticVariable var) {
exists(InitializeIndirectionInstruction instr | instr.getIRVariable() = var)
} or
TDynamicAllocation(CallInstruction call) {
Expand Down Expand Up @@ -74,7 +74,7 @@ class VariableAllocation extends Allocation, TVariableAllocation {
}

class IndirectParameterAllocation extends Allocation, TIndirectParameterAllocation {
IRAutomaticUserVariable var;
IRAutomaticVariable var;

IndirectParameterAllocation() { this = TIndirectParameterAllocation(var) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ class IREllipsisVariable extends IRTempVariable {
final override string toString() { result = "#ellipsis" }
}

/**
* A temporary variable generated to hold the `this` pointer.
*/
class IRThisVariable extends IRTempVariable {
IRThisVariable() { tag = ThisTempVar() }

final override string toString() { result = "#this" }
}

/**
* A variable generated to represent the contents of a string literal. This variable acts much like
* a read-only global variable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ private module Cached {
getTranslatedFunction(func).hasUserVariable(var, type)
}

cached
predicate hasThisVariable(Function func, CppType type) {
type = getTypeForGLValue(getTranslatedFunction(func).getThisType())
}

cached
predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag, CppType type) {
exists(TranslatedElement element |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ private import cpp

newtype TInstructionTag =
OnlyInstructionTag() or // Single instruction (not including implicit Load)
InitializeThisTag() or
InitializerVariableAddressTag() or
InitializerLoadStringTag() or
InitializerStoreTag() or
Expand Down Expand Up @@ -70,7 +69,9 @@ newtype TInstructionTag =
VarArgsMoveNextTag() or
VarArgsVAListStoreTag() or
AsmTag() or
AsmInputTag(int elementIndex) { exists(AsmStmt asm | exists(asm.getChild(elementIndex))) }
AsmInputTag(int elementIndex) { exists(AsmStmt asm | exists(asm.getChild(elementIndex))) } or
ThisAddressTag() or
ThisLoadTag()

class InstructionTag extends TInstructionTag {
final string toString() { result = "Tag" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,9 @@ newtype TTranslatedElement =
TTranslatedConstructorInitList(Function func) { translateFunction(func) } or
// A destructor destruction list
TTranslatedDestructorDestructionList(Function func) { translateFunction(func) } or
TTranslatedThisParameter(Function func) {
translateFunction(func) and func.isMember() and not func.isStatic()
} or
// A function parameter
TTranslatedParameter(Parameter param) {
exists(Function func |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -664,31 +664,40 @@ class TranslatedThisExpr extends TranslatedNonConstantExpr {
final override TranslatedElement getChild(int id) { none() }

final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
opcode instanceof Opcode::CopyValue and
tag = ThisAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getTypeForGLValue(any(UnknownType t))
or
tag = ThisLoadTag() and
opcode instanceof Opcode::Load and
resultType = getResultType()
}

final override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
final override Instruction getResult() { result = getInstruction(ThisLoadTag()) }

final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
final override Instruction getFirstInstruction() { result = getInstruction(ThisAddressTag()) }

final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
tag = OnlyInstructionTag() and
tag = ThisAddressTag() and
result = getInstruction(ThisLoadTag())
or
kind instanceof GotoEdge and
tag = ThisLoadTag() and
result = getParent().getChildSuccessor(this)
}

final override Instruction getChildSuccessor(TranslatedElement child) { none() }

final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
result = getInitializeThisInstruction()
tag = ThisLoadTag() and
operandTag instanceof AddressOperandTag and
result = getInstruction(ThisAddressTag())
}

private Instruction getInitializeThisInstruction() {
result = getTranslatedFunction(expr.getEnclosingFunction()).getInitializeThisInstruction()
override IRVariable getInstructionVariable(InstructionTag tag) {
tag = ThisAddressTag() and
result = this.getEnclosingFunction().getThisVariable()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
final override Function getFunction() { result = func }

final override TranslatedElement getChild(int id) {
id = -4 and result = getReadEffects()
id = -5 and result = getReadEffects()
or
id = -3 and result = getConstructorInitList()
id = -4 and result = getConstructorInitList()
or
id = -2 and result = getBody()
id = -3 and result = getBody()
or
id = -1 and result = getDestructorDestructionList()
id = -2 and result = getDestructorDestructionList()
or
id >= 0 and result = getParameter(id)
id >= -1 and result = getParameter(id)
}

final private TranslatedConstructorInitList getConstructorInitList() {
Expand All @@ -97,6 +97,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
final private TranslatedReadEffects getReadEffects() { result = getTranslatedReadEffects(func) }

final private TranslatedParameter getParameter(int index) {
result = getTranslatedThisParameter(func) and
index = -1
or
result = getTranslatedParameter(func.getParameter(index))
or
index = getEllipsisParameterIndexForFunction(func) and
Expand All @@ -117,20 +120,13 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
(
tag = InitializeNonLocalTag() and
if exists(getThisType())
then result = getInstruction(InitializeThisTag())
then result = getParameter(-1).getFirstInstruction()
else
if exists(getParameter(0))
then result = getParameter(0).getFirstInstruction()
else result = getBody().getFirstInstruction()
)
or
(
tag = InitializeThisTag() and
if exists(getParameter(0))
then result = getParameter(0).getFirstInstruction()
else result = getConstructorInitList().getFirstInstruction()
)
or
tag = ReturnValueAddressTag() and
result = getInstruction(ReturnTag())
or
Expand Down Expand Up @@ -184,10 +180,6 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
opcode instanceof Opcode::InitializeNonLocal and
resultType = getUnknownType()
or
tag = InitializeThisTag() and
opcode instanceof Opcode::InitializeThis and
resultType = getTypeForGLValue(getThisType())
or
tag = ReturnValueAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getTypeForGLValue(getReturnType()) and
Expand Down Expand Up @@ -228,10 +220,8 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = ReturnTag() and
hasReturnValue() and
(
operandTag instanceof AddressOperandTag and
result = getInstruction(ReturnValueAddressTag())
)
operandTag instanceof AddressOperandTag and
result = getInstruction(ReturnValueAddressTag())
}

final override CppType getInstructionMemoryOperandType(
Expand Down Expand Up @@ -264,6 +254,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
tag = EllipsisTempVar() and
func.isVarargs() and
type = getEllipsisVariablePRValueType()
or
tag = ThisTempVar() and
type = getTypeForGLValue(getThisType())
}

/**
Expand All @@ -286,6 +279,11 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
*/
final IREllipsisVariable getEllipsisVariable() { result.getEnclosingFunction() = func }

/**
* Gets the variable that represents the `this` pointer for this function, if any.
*/
final IRThisVariable getThisVariable() { result = getIRTempVariable(func, ThisTempVar()) }

/**
* Holds if the function has a non-`void` return type.
*/
Expand All @@ -295,7 +293,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
* Gets the single `InitializeThis` instruction for this function. Holds only
* if the function is an instance member function, constructor, or destructor.
*/
final Instruction getInitializeThisInstruction() { result = getInstruction(InitializeThisTag()) }
final Instruction getInitializeThisInstruction() {
result = getTranslatedThisParameter(func).getInstruction(InitializerStoreTag())
}

/**
* Gets the type pointed to by the `this` pointer for this function (i.e. `*this`).
Expand Down Expand Up @@ -336,6 +336,11 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
final Type getReturnType() { result = func.getType() }
}

/**
* Gets the `TranslatedThisParameter` for function `func`, if one exists.
*/
TranslatedThisParameter getTranslatedThisParameter(Function func) { result.getFunction() = func }

/**
* Gets the `TranslatedPositionalParameter` that represents parameter `param`.
*/
Expand All @@ -350,8 +355,9 @@ TranslatedEllipsisParameter getTranslatedEllipsisParameter(Function func) {

/**
* The IR translation of a parameter to a function. This can be either a user-declared parameter
* (`TranslatedPositionParameter`) or the synthesized parameter used to represent a `...` in a
* varargs function (`TranslatedEllipsisParameter`).
* (`TranslatedPositionParameter`), the synthesized parameter used to represent `this`, or the
* synthesized parameter used to represent a `...` in a varargs function
* (`TranslatedEllipsisParameter`).
*/
abstract class TranslatedParameter extends TranslatedElement {
final override TranslatedElement getChild(int id) { none() }
Expand Down Expand Up @@ -398,7 +404,7 @@ abstract class TranslatedParameter extends TranslatedElement {
hasIndirection() and
tag = InitializerIndirectStoreTag() and
opcode instanceof Opcode::InitializeIndirection and
resultType = getUnknownType()
resultType = getInitializationResultType()
}

final override IRVariable getInstructionVariable(InstructionTag tag) {
Expand Down Expand Up @@ -435,9 +441,43 @@ abstract class TranslatedParameter extends TranslatedElement {

abstract CppType getPRValueType();

abstract CppType getInitializationResultType();

abstract IRAutomaticVariable getIRVariable();
}

/**
* The IR translation of the synthesized parameter used to represent the `...` in a varargs
* function.
*/
class TranslatedThisParameter extends TranslatedParameter, TTranslatedThisParameter {
Function func;

TranslatedThisParameter() { this = TTranslatedThisParameter(func) }

final override string toString() { result = "this" }

final override Locatable getAST() { result = func }

final override Function getFunction() { result = func }

final override predicate hasIndirection() { any() }

final override CppType getGLValueType() { result = getTypeForGLValue(any(UnknownType t)) }

final override CppType getPRValueType() {
result = getTypeForGLValue(getTranslatedFunction(func).getThisType())
}

final override CppType getInitializationResultType() {
result = getTypeForPRValue(getTranslatedFunction(func).getThisType())
}

final override IRThisVariable getIRVariable() {
result = getTranslatedFunction(func).getThisVariable()
}
}

/**
* Represents the IR translation of a function parameter, including the
* initialization of that parameter with the incoming argument.
Expand Down Expand Up @@ -468,6 +508,8 @@ class TranslatedPositionalParameter extends TranslatedParameter, TTranslatedPara

final override CppType getPRValueType() { result = getTypeForPRValue(getVariableType(param)) }

final override CppType getInitializationResultType() { result = getUnknownType() }

final override IRAutomaticUserVariable getIRVariable() {
result = getIRUserVariable(getFunction(), param)
}
Expand All @@ -494,6 +536,8 @@ class TranslatedEllipsisParameter extends TranslatedParameter, TTranslatedEllips

final override CppType getPRValueType() { result = getEllipsisVariablePRValueType() }

final override CppType getInitializationResultType() { result = getUnknownType() }

final override IREllipsisVariable getIRVariable() {
result = getTranslatedFunction(func).getEllipsisVariable()
}
Expand Down
Loading