Skip to content

Commit 0d8472b

Browse files
authored
Merge pull request github#3571 from rdmarsh2/ir-this-parameter
Treat `this` as a parameter in IR generation
2 parents 2b90b50 + d8b5d3b commit 0d8472b

30 files changed

+1402
-984
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,7 @@ class ExprNode extends InstructionNode {
160160
* as `x` in `f(x)` and implicit parameters such as `this` in `x.f()`
161161
*/
162162
class ParameterNode extends InstructionNode {
163-
ParameterNode() {
164-
instr instanceof InitializeParameterInstruction
165-
or
166-
instr instanceof InitializeThisInstruction
167-
}
163+
override InitializeParameterInstruction instr;
168164

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

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

@@ -189,7 +185,7 @@ private class ExplicitParameterNode extends ParameterNode {
189185
}
190186

191187
private class ThisParameterNode extends ParameterNode {
192-
override InitializeThisInstruction instr;
188+
ThisParameterNode() { instr.getIRVariable() instanceof IRThisVariable }
193189

194190
override predicate isParameterOf(Function f, int i) {
195191
i = -1 and instr.getEnclosingFunction() = f

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ class IREllipsisVariable extends IRTempVariable {
223223
final override string toString() { result = "#ellipsis" }
224224
}
225225

226+
/**
227+
* A temporary variable generated to hold the `this` pointer.
228+
*/
229+
class IRThisVariable extends IRTempVariable {
230+
IRThisVariable() { tag = ThisTempVar() }
231+
232+
final override string toString() { result = "#this" }
233+
}
234+
226235
/**
227236
* A variable generated to represent the contents of a string literal. This variable acts much like
228237
* a read-only global variable.

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ private predicate isArgumentForParameter(CallInstruction ci, Operand operand, In
204204
init.(InitializeParameterInstruction).getParameter() =
205205
f.getParameter(operand.(PositionalArgumentOperand).getIndex())
206206
or
207-
init instanceof InitializeThisInstruction and
207+
init.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable and
208208
init.getEnclosingFunction() = f and
209209
operand instanceof ThisArgumentOperand
210210
) and

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ private import AliasAnalysis
55

66
private newtype TAllocation =
77
TVariableAllocation(IRVariable var) or
8-
TIndirectParameterAllocation(IRAutomaticUserVariable var) {
8+
TIndirectParameterAllocation(IRAutomaticVariable var) {
99
exists(InitializeIndirectionInstruction instr | instr.getIRVariable() = var)
1010
} or
1111
TDynamicAllocation(CallInstruction call) {
@@ -74,7 +74,7 @@ class VariableAllocation extends Allocation, TVariableAllocation {
7474
}
7575

7676
class IndirectParameterAllocation extends Allocation, TIndirectParameterAllocation {
77-
IRAutomaticUserVariable var;
77+
IRAutomaticVariable var;
7878

7979
IndirectParameterAllocation() { this = TIndirectParameterAllocation(var) }
8080

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ class IREllipsisVariable extends IRTempVariable {
223223
final override string toString() { result = "#ellipsis" }
224224
}
225225

226+
/**
227+
* A temporary variable generated to hold the `this` pointer.
228+
*/
229+
class IRThisVariable extends IRTempVariable {
230+
IRThisVariable() { tag = ThisTempVar() }
231+
232+
final override string toString() { result = "#this" }
233+
}
234+
226235
/**
227236
* A variable generated to represent the contents of a string literal. This variable acts much like
228237
* a read-only global variable.

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ private module Cached {
3535
getTranslatedFunction(func).hasUserVariable(var, type)
3636
}
3737

38+
cached
39+
predicate hasThisVariable(Function func, CppType type) {
40+
type = getTypeForGLValue(getTranslatedFunction(func).getThisType())
41+
}
42+
3843
cached
3944
predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag, CppType type) {
4045
exists(TranslatedElement element |

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ private import cpp
22

33
newtype TInstructionTag =
44
OnlyInstructionTag() or // Single instruction (not including implicit Load)
5-
InitializeThisTag() or
65
InitializerVariableAddressTag() or
76
InitializerLoadStringTag() or
87
InitializerStoreTag() or
@@ -70,7 +69,9 @@ newtype TInstructionTag =
7069
VarArgsMoveNextTag() or
7170
VarArgsVAListStoreTag() or
7271
AsmTag() or
73-
AsmInputTag(int elementIndex) { exists(AsmStmt asm | exists(asm.getChild(elementIndex))) }
72+
AsmInputTag(int elementIndex) { exists(AsmStmt asm | exists(asm.getChild(elementIndex))) } or
73+
ThisAddressTag() or
74+
ThisLoadTag()
7475

7576
class InstructionTag extends TInstructionTag {
7677
final string toString() { result = "Tag" }

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,9 @@ newtype TTranslatedElement =
400400
TTranslatedConstructorInitList(Function func) { translateFunction(func) } or
401401
// A destructor destruction list
402402
TTranslatedDestructorDestructionList(Function func) { translateFunction(func) } or
403+
TTranslatedThisParameter(Function func) {
404+
translateFunction(func) and func.isMember() and not func.isStatic()
405+
} or
403406
// A function parameter
404407
TTranslatedParameter(Parameter param) {
405408
exists(Function func |

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -664,31 +664,40 @@ class TranslatedThisExpr extends TranslatedNonConstantExpr {
664664
final override TranslatedElement getChild(int id) { none() }
665665

666666
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
667-
tag = OnlyInstructionTag() and
668-
opcode instanceof Opcode::CopyValue and
667+
tag = ThisAddressTag() and
668+
opcode instanceof Opcode::VariableAddress and
669+
resultType = getTypeForGLValue(any(UnknownType t))
670+
or
671+
tag = ThisLoadTag() and
672+
opcode instanceof Opcode::Load and
669673
resultType = getResultType()
670674
}
671675

672-
final override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
676+
final override Instruction getResult() { result = getInstruction(ThisLoadTag()) }
673677

674-
final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
678+
final override Instruction getFirstInstruction() { result = getInstruction(ThisAddressTag()) }
675679

676680
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
677681
kind instanceof GotoEdge and
678-
tag = OnlyInstructionTag() and
682+
tag = ThisAddressTag() and
683+
result = getInstruction(ThisLoadTag())
684+
or
685+
kind instanceof GotoEdge and
686+
tag = ThisLoadTag() and
679687
result = getParent().getChildSuccessor(this)
680688
}
681689

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

684692
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
685-
tag = OnlyInstructionTag() and
686-
operandTag instanceof UnaryOperandTag and
687-
result = getInitializeThisInstruction()
693+
tag = ThisLoadTag() and
694+
operandTag instanceof AddressOperandTag and
695+
result = getInstruction(ThisAddressTag())
688696
}
689697

690-
private Instruction getInitializeThisInstruction() {
691-
result = getTranslatedFunction(expr.getEnclosingFunction()).getInitializeThisInstruction()
698+
override IRVariable getInstructionVariable(InstructionTag tag) {
699+
tag = ThisAddressTag() and
700+
result = this.getEnclosingFunction().getThisVariable()
692701
}
693702
}
694703

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,15 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
7373
final override Function getFunction() { result = func }
7474

7575
final override TranslatedElement getChild(int id) {
76-
id = -4 and result = getReadEffects()
76+
id = -5 and result = getReadEffects()
7777
or
78-
id = -3 and result = getConstructorInitList()
78+
id = -4 and result = getConstructorInitList()
7979
or
80-
id = -2 and result = getBody()
80+
id = -3 and result = getBody()
8181
or
82-
id = -1 and result = getDestructorDestructionList()
82+
id = -2 and result = getDestructorDestructionList()
8383
or
84-
id >= 0 and result = getParameter(id)
84+
id >= -1 and result = getParameter(id)
8585
}
8686

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

9999
final private TranslatedParameter getParameter(int index) {
100+
result = getTranslatedThisParameter(func) and
101+
index = -1
102+
or
100103
result = getTranslatedParameter(func.getParameter(index))
101104
or
102105
index = getEllipsisParameterIndexForFunction(func) and
@@ -117,20 +120,13 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
117120
(
118121
tag = InitializeNonLocalTag() and
119122
if exists(getThisType())
120-
then result = getInstruction(InitializeThisTag())
123+
then result = getParameter(-1).getFirstInstruction()
121124
else
122125
if exists(getParameter(0))
123126
then result = getParameter(0).getFirstInstruction()
124127
else result = getBody().getFirstInstruction()
125128
)
126129
or
127-
(
128-
tag = InitializeThisTag() and
129-
if exists(getParameter(0))
130-
then result = getParameter(0).getFirstInstruction()
131-
else result = getConstructorInitList().getFirstInstruction()
132-
)
133-
or
134130
tag = ReturnValueAddressTag() and
135131
result = getInstruction(ReturnTag())
136132
or
@@ -184,10 +180,6 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
184180
opcode instanceof Opcode::InitializeNonLocal and
185181
resultType = getUnknownType()
186182
or
187-
tag = InitializeThisTag() and
188-
opcode instanceof Opcode::InitializeThis and
189-
resultType = getTypeForGLValue(getThisType())
190-
or
191183
tag = ReturnValueAddressTag() and
192184
opcode instanceof Opcode::VariableAddress and
193185
resultType = getTypeForGLValue(getReturnType()) and
@@ -228,10 +220,8 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
228220
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
229221
tag = ReturnTag() and
230222
hasReturnValue() and
231-
(
232-
operandTag instanceof AddressOperandTag and
233-
result = getInstruction(ReturnValueAddressTag())
234-
)
223+
operandTag instanceof AddressOperandTag and
224+
result = getInstruction(ReturnValueAddressTag())
235225
}
236226

237227
final override CppType getInstructionMemoryOperandType(
@@ -264,6 +254,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
264254
tag = EllipsisTempVar() and
265255
func.isVarargs() and
266256
type = getEllipsisVariablePRValueType()
257+
or
258+
tag = ThisTempVar() and
259+
type = getTypeForGLValue(getThisType())
267260
}
268261

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

282+
/**
283+
* Gets the variable that represents the `this` pointer for this function, if any.
284+
*/
285+
final IRThisVariable getThisVariable() { result = getIRTempVariable(func, ThisTempVar()) }
286+
289287
/**
290288
* Holds if the function has a non-`void` return type.
291289
*/
@@ -295,7 +293,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
295293
* Gets the single `InitializeThis` instruction for this function. Holds only
296294
* if the function is an instance member function, constructor, or destructor.
297295
*/
298-
final Instruction getInitializeThisInstruction() { result = getInstruction(InitializeThisTag()) }
296+
final Instruction getInitializeThisInstruction() {
297+
result = getTranslatedThisParameter(func).getInstruction(InitializerStoreTag())
298+
}
299299

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

339+
/**
340+
* Gets the `TranslatedThisParameter` for function `func`, if one exists.
341+
*/
342+
TranslatedThisParameter getTranslatedThisParameter(Function func) { result.getFunction() = func }
343+
339344
/**
340345
* Gets the `TranslatedPositionalParameter` that represents parameter `param`.
341346
*/
@@ -350,8 +355,9 @@ TranslatedEllipsisParameter getTranslatedEllipsisParameter(Function func) {
350355

351356
/**
352357
* The IR translation of a parameter to a function. This can be either a user-declared parameter
353-
* (`TranslatedPositionParameter`) or the synthesized parameter used to represent a `...` in a
354-
* varargs function (`TranslatedEllipsisParameter`).
358+
* (`TranslatedPositionParameter`), the synthesized parameter used to represent `this`, or the
359+
* synthesized parameter used to represent a `...` in a varargs function
360+
* (`TranslatedEllipsisParameter`).
355361
*/
356362
abstract class TranslatedParameter extends TranslatedElement {
357363
final override TranslatedElement getChild(int id) { none() }
@@ -398,7 +404,7 @@ abstract class TranslatedParameter extends TranslatedElement {
398404
hasIndirection() and
399405
tag = InitializerIndirectStoreTag() and
400406
opcode instanceof Opcode::InitializeIndirection and
401-
resultType = getUnknownType()
407+
resultType = getInitializationResultType()
402408
}
403409

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

436442
abstract CppType getPRValueType();
437443

444+
abstract CppType getInitializationResultType();
445+
438446
abstract IRAutomaticVariable getIRVariable();
439447
}
440448

449+
/**
450+
* The IR translation of the synthesized parameter used to represent the `...` in a varargs
451+
* function.
452+
*/
453+
class TranslatedThisParameter extends TranslatedParameter, TTranslatedThisParameter {
454+
Function func;
455+
456+
TranslatedThisParameter() { this = TTranslatedThisParameter(func) }
457+
458+
final override string toString() { result = "this" }
459+
460+
final override Locatable getAST() { result = func }
461+
462+
final override Function getFunction() { result = func }
463+
464+
final override predicate hasIndirection() { any() }
465+
466+
final override CppType getGLValueType() { result = getTypeForGLValue(any(UnknownType t)) }
467+
468+
final override CppType getPRValueType() {
469+
result = getTypeForGLValue(getTranslatedFunction(func).getThisType())
470+
}
471+
472+
final override CppType getInitializationResultType() {
473+
result = getTypeForPRValue(getTranslatedFunction(func).getThisType())
474+
}
475+
476+
final override IRThisVariable getIRVariable() {
477+
result = getTranslatedFunction(func).getThisVariable()
478+
}
479+
}
480+
441481
/**
442482
* Represents the IR translation of a function parameter, including the
443483
* initialization of that parameter with the incoming argument.
@@ -468,6 +508,8 @@ class TranslatedPositionalParameter extends TranslatedParameter, TTranslatedPara
468508

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

511+
final override CppType getInitializationResultType() { result = getUnknownType() }
512+
471513
final override IRAutomaticUserVariable getIRVariable() {
472514
result = getIRUserVariable(getFunction(), param)
473515
}
@@ -494,6 +536,8 @@ class TranslatedEllipsisParameter extends TranslatedParameter, TTranslatedEllips
494536

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

539+
final override CppType getInitializationResultType() { result = getUnknownType() }
540+
497541
final override IREllipsisVariable getIRVariable() {
498542
result = getTranslatedFunction(func).getEllipsisVariable()
499543
}

0 commit comments

Comments
 (0)