Skip to content

Commit 0b2c262

Browse files
authored
Merge pull request #2184 from dave-bartolomeo/dave/AliasedUse
C++/C#: Add `AliasedUse` instruction to all functions
2 parents 04e3683 + cc5a689 commit 0b2c262

File tree

25 files changed

+689
-344
lines changed

25 files changed

+689
-344
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ private newtype TMemoryAccessKind =
55
TBufferMayMemoryAccess() or
66
TEscapedMemoryAccess() or
77
TEscapedMayMemoryAccess() or
8+
TNonLocalMayMemoryAccess() or
89
TPhiMemoryAccess() or
910
TUnmodeledMemoryAccess() or
1011
TChiTotalMemoryAccess() or
@@ -80,6 +81,14 @@ class EscapedMayMemoryAccess extends MemoryAccessKind, TEscapedMayMemoryAccess {
8081
override string toString() { result = "escaped(may)" }
8182
}
8283

84+
/**
85+
* The operand or result may access all memory whose address has escaped, other than data on the
86+
* stack frame of the current function.
87+
*/
88+
class NonLocalMayMemoryAccess extends MemoryAccessKind, TNonLocalMayMemoryAccess {
89+
override string toString() { result = "nonlocal(may)" }
90+
}
91+
8392
/**
8493
* The operand is a Phi operand, which accesses the same memory as its
8594
* definition.

cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ private newtype TOpcode =
5757
TUnmodeledDefinition() or
5858
TUnmodeledUse() or
5959
TAliasedDefinition() or
60+
TAliasedUse() or
6061
TPhi() or
6162
TBuiltIn() or
6263
TVarArgsStart() or
@@ -393,6 +394,10 @@ module Opcode {
393394
final override string toString() { result = "AliasedDefinition" }
394395
}
395396

397+
class AliasedUse extends Opcode, TAliasedUse {
398+
final override string toString() { result = "AliasedUse" }
399+
}
400+
396401
class Phi extends Opcode, TPhi {
397402
final override string toString() { result = "Phi" }
398403
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ module InstructionSanity {
5050
(
5151
opcode instanceof ReadSideEffectOpcode or
5252
opcode instanceof Opcode::InlineAsm or
53-
opcode instanceof Opcode::CallSideEffect
53+
opcode instanceof Opcode::CallSideEffect or
54+
opcode instanceof Opcode::AliasedUse
5455
) and
5556
tag instanceof SideEffectOperandTag
5657
)
@@ -263,6 +264,7 @@ module InstructionSanity {
263264
) {
264265
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
265266
not useOperand.getUse() instanceof UnmodeledUseInstruction and
267+
not defInstr instanceof UnmodeledDefinitionInstruction and
266268
pointOfEvaluation(useOperand, useBlock, useIndex) and
267269
defInstr = useOperand.getAnyDef() and
268270
(
@@ -1421,6 +1423,13 @@ class AliasedDefinitionInstruction extends Instruction {
14211423
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
14221424
}
14231425

1426+
/**
1427+
* An instruction that consumes all escaped memory on exit from the function.
1428+
*/
1429+
class AliasedUseInstruction extends Instruction {
1430+
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
1431+
}
1432+
14241433
class UnmodeledUseInstruction extends Instruction {
14251434
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }
14261435

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand {
396396
override SideEffectOperandTag tag;
397397

398398
override MemoryAccessKind getMemoryAccess() {
399+
useInstr instanceof AliasedUseInstruction and
400+
result instanceof NonLocalMayMemoryAccess
401+
or
399402
useInstr instanceof CallSideEffectInstruction and
400403
result instanceof EscapedMayMemoryAccess
401404
or

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ private newtype TMemoryLocation =
4545
languageType = type.getCanonicalLanguageType()
4646
} or
4747
TUnknownMemoryLocation(IRFunction irFunc) or
48+
TUnknownNonLocalMemoryLocation(IRFunction irFunc) or
4849
TUnknownVirtualVariable(IRFunction irFunc)
4950

5051
/**
@@ -162,6 +163,26 @@ class UnknownMemoryLocation extends TUnknownMemoryLocation, MemoryLocation {
162163
final override string getUniqueId() { result = "{Unknown}" }
163164
}
164165

166+
/**
167+
* An access to memory that is not known to be confined to a specific `IRVariable`, but is known to
168+
* not access memory on the current function's stack frame.
169+
*/
170+
class UnknownNonLocalMemoryLocation extends TUnknownNonLocalMemoryLocation, MemoryLocation {
171+
IRFunction irFunc;
172+
173+
UnknownNonLocalMemoryLocation() { this = TUnknownNonLocalMemoryLocation(irFunc) }
174+
175+
final override string toString() { result = "{UnknownNonLocal}" }
176+
177+
final override VirtualVariable getVirtualVariable() { result = TUnknownVirtualVariable(irFunc) }
178+
179+
final override Language::LanguageType getType() {
180+
result = any(IRUnknownType type).getCanonicalLanguageType()
181+
}
182+
183+
final override string getUniqueId() { result = "{UnknownNonLocal}" }
184+
}
185+
165186
/**
166187
* An access to all aliased memory.
167188
*/
@@ -194,6 +215,13 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
194215
def instanceof UnknownMemoryLocation and
195216
result instanceof MayPartiallyOverlap
196217
or
218+
// An UnknownNonLocalMemoryLocation may partially overlap any location within the same virtual
219+
// variable, except a local variable.
220+
def.getVirtualVariable() = use.getVirtualVariable() and
221+
def instanceof UnknownNonLocalMemoryLocation and
222+
result instanceof MayPartiallyOverlap and
223+
not use.(VariableMemoryLocation).getVariable() instanceof IRAutomaticVariable
224+
or
197225
exists(VariableMemoryLocation defVariableLocation |
198226
defVariableLocation = def and
199227
(
@@ -202,6 +230,13 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
202230
(use instanceof UnknownMemoryLocation or use instanceof UnknownVirtualVariable) and
203231
result instanceof MayPartiallyOverlap
204232
or
233+
// A VariableMemoryLocation that is not a local variable may partially overlap an unknown
234+
// non-local location within the same virtual variable.
235+
def.getVirtualVariable() = use.getVirtualVariable() and
236+
use instanceof UnknownNonLocalMemoryLocation and
237+
result instanceof MayPartiallyOverlap and
238+
not defVariableLocation.getVariable() instanceof IRAutomaticVariable
239+
or
205240
// A VariableMemoryLocation overlaps another location within the same variable based on the relationship
206241
// of the two offset intervals.
207242
exists(Overlap intervalOverlap |
@@ -327,6 +362,9 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
327362
or
328363
kind instanceof EscapedMayMemoryAccess and
329364
result = TUnknownMemoryLocation(instr.getEnclosingIRFunction())
365+
or
366+
kind instanceof NonLocalMayMemoryAccess and
367+
result = TUnknownNonLocalMemoryLocation(instr.getEnclosingIRFunction())
330368
)
331369
)
332370
}
@@ -351,6 +389,9 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
351389
or
352390
kind instanceof EscapedMayMemoryAccess and
353391
result = TUnknownMemoryLocation(operand.getEnclosingIRFunction())
392+
or
393+
kind instanceof NonLocalMayMemoryAccess and
394+
result = TUnknownNonLocalMemoryLocation(operand.getEnclosingIRFunction())
354395
)
355396
)
356397
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ module InstructionSanity {
5050
(
5151
opcode instanceof ReadSideEffectOpcode or
5252
opcode instanceof Opcode::InlineAsm or
53-
opcode instanceof Opcode::CallSideEffect
53+
opcode instanceof Opcode::CallSideEffect or
54+
opcode instanceof Opcode::AliasedUse
5455
) and
5556
tag instanceof SideEffectOperandTag
5657
)
@@ -263,6 +264,7 @@ module InstructionSanity {
263264
) {
264265
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
265266
not useOperand.getUse() instanceof UnmodeledUseInstruction and
267+
not defInstr instanceof UnmodeledDefinitionInstruction and
266268
pointOfEvaluation(useOperand, useBlock, useIndex) and
267269
defInstr = useOperand.getAnyDef() and
268270
(
@@ -1421,6 +1423,13 @@ class AliasedDefinitionInstruction extends Instruction {
14211423
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
14221424
}
14231425

1426+
/**
1427+
* An instruction that consumes all escaped memory on exit from the function.
1428+
*/
1429+
class AliasedUseInstruction extends Instruction {
1430+
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
1431+
}
1432+
14241433
class UnmodeledUseInstruction extends Instruction {
14251434
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }
14261435

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand {
396396
override SideEffectOperandTag tag;
397397

398398
override MemoryAccessKind getMemoryAccess() {
399+
useInstr instanceof AliasedUseInstruction and
400+
result instanceof NonLocalMayMemoryAccess
401+
or
399402
useInstr instanceof CallSideEffectInstruction and
400403
result instanceof EscapedMayMemoryAccess
401404
or

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ newtype TInstructionTag =
2626
UnmodeledDefinitionTag() or
2727
UnmodeledUseTag() or
2828
AliasedDefinitionTag() or
29+
AliasedUseTag() or
2930
SwitchBranchTag() or
3031
CallTargetTag() or
3132
CallTag() or
@@ -118,6 +119,8 @@ string getInstructionTagId(TInstructionTag tag) {
118119
or
119120
tag = AliasedDefinitionTag() and result = "AliasedDef"
120121
or
122+
tag = AliasedUseTag() and result = "AliasedUse"
123+
or
121124
tag = SwitchBranchTag() and result = "SwitchBranch"
122125
or
123126
tag = CallTargetTag() and result = "CallTarget"

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
9696
result = getInstruction(UnmodeledUseTag())
9797
or
9898
tag = UnmodeledUseTag() and
99+
result = getInstruction(AliasedUseTag())
100+
or
101+
tag = AliasedUseTag() and
99102
result = getInstruction(ExitFunctionTag())
100103
)
101104
}
@@ -167,6 +170,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
167170
opcode instanceof Opcode::UnmodeledUse and
168171
resultType = getVoidType()
169172
or
173+
tag = AliasedUseTag() and
174+
opcode instanceof Opcode::AliasedUse and
175+
resultType = getVoidType()
176+
or
170177
tag = ExitFunctionTag() and
171178
opcode instanceof Opcode::ExitFunction and
172179
resultType = getVoidType()
@@ -187,6 +194,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
187194
operandTag instanceof UnmodeledUseOperandTag and
188195
result = getUnmodeledDefinitionInstruction()
189196
or
197+
tag = AliasedUseTag() and
198+
operandTag instanceof SideEffectOperandTag and
199+
result = getUnmodeledDefinitionInstruction()
200+
or
190201
tag = ReturnTag() and
191202
hasReturnValue() and
192203
(
@@ -203,6 +214,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
203214
hasReturnValue() and
204215
operandTag instanceof LoadOperandTag and
205216
result = getTypeForPRValue(getReturnType())
217+
or
218+
tag = AliasedUseTag() and
219+
operandTag instanceof SideEffectOperandTag and
220+
result = getUnknownType()
206221
}
207222

208223
final override IRVariable getInstructionVariable(InstructionTag tag) {

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ module InstructionSanity {
5050
(
5151
opcode instanceof ReadSideEffectOpcode or
5252
opcode instanceof Opcode::InlineAsm or
53-
opcode instanceof Opcode::CallSideEffect
53+
opcode instanceof Opcode::CallSideEffect or
54+
opcode instanceof Opcode::AliasedUse
5455
) and
5556
tag instanceof SideEffectOperandTag
5657
)
@@ -263,6 +264,7 @@ module InstructionSanity {
263264
) {
264265
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
265266
not useOperand.getUse() instanceof UnmodeledUseInstruction and
267+
not defInstr instanceof UnmodeledDefinitionInstruction and
266268
pointOfEvaluation(useOperand, useBlock, useIndex) and
267269
defInstr = useOperand.getAnyDef() and
268270
(
@@ -1421,6 +1423,13 @@ class AliasedDefinitionInstruction extends Instruction {
14211423
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
14221424
}
14231425

1426+
/**
1427+
* An instruction that consumes all escaped memory on exit from the function.
1428+
*/
1429+
class AliasedUseInstruction extends Instruction {
1430+
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
1431+
}
1432+
14241433
class UnmodeledUseInstruction extends Instruction {
14251434
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }
14261435

0 commit comments

Comments
 (0)