Skip to content

Commit 5b5d2f2

Browse files
author
Dave Bartolomeo
authored
Merge pull request #2154 from rdmarsh2/rdmarsh/cpp/ir-callee-side-effects
C++: add InitializeIndirection for pointer params
2 parents cc7f98e + e209ed9 commit 5b5d2f2

File tree

27 files changed

+1444
-969
lines changed

27 files changed

+1444
-969
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ private newtype TOpcode =
33
TUninitialized() or
44
TError() or
55
TInitializeParameter() or
6+
TInitializeIndirection() or
67
TInitializeThis() or
78
TEnterFunction() or
89
TExitFunction() or
910
TReturnValue() or
1011
TReturnVoid() or
12+
TReturnIndirection() or
1113
TCopyValue() or
1214
TLoad() or
1315
TStore() or
@@ -180,6 +182,10 @@ module Opcode {
180182
final override string toString() { result = "InitializeParameter" }
181183
}
182184

185+
class InitializeIndirection extends MemoryAccessOpcode, TInitializeIndirection {
186+
final override string toString() { result = "InitializeIndirection" }
187+
}
188+
183189
class InitializeThis extends Opcode, TInitializeThis {
184190
final override string toString() { result = "InitializeThis" }
185191
}
@@ -200,6 +206,10 @@ module Opcode {
200206
final override string toString() { result = "ReturnVoid" }
201207
}
202208

209+
class ReturnIndirection extends MemoryAccessOpcode, TReturnIndirection {
210+
final override string toString() { result = "ReturnIndirection" }
211+
}
212+
203213
class CopyValue extends UnaryOpcode, CopyOpcode, TCopyValue {
204214
final override string toString() { result = "CopyValue" }
205215
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ module InstructionSanity {
5151
opcode instanceof ReadSideEffectOpcode or
5252
opcode instanceof Opcode::InlineAsm or
5353
opcode instanceof Opcode::CallSideEffect or
54+
opcode instanceof Opcode::ReturnIndirection or
5455
opcode instanceof Opcode::AliasedUse
5556
) and
5657
tag instanceof SideEffectOperandTag
@@ -713,6 +714,14 @@ class InitializeParameterInstruction extends VariableInstruction {
713714
final override MemoryAccessKind getResultMemoryAccess() { result instanceof IndirectMemoryAccess }
714715
}
715716

717+
class InitializeIndirectionInstruction extends VariableInstruction {
718+
InitializeIndirectionInstruction() { getOpcode() instanceof Opcode::InitializeIndirection }
719+
720+
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
721+
722+
final override MemoryAccessKind getResultMemoryAccess() { result instanceof IndirectMemoryAccess }
723+
}
724+
716725
/**
717726
* An instruction that initializes the `this` pointer parameter of the enclosing function.
718727
*/
@@ -773,6 +782,18 @@ class ReturnValueInstruction extends ReturnInstruction {
773782
final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
774783
}
775784

785+
class ReturnIndirectionInstruction extends Instruction {
786+
ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
787+
788+
final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
789+
790+
final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
791+
792+
final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
793+
794+
final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
795+
}
796+
776797
class CopyInstruction extends Instruction {
777798
CopyInstruction() { getOpcode() instanceof CopyOpcode }
778799

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
@@ -410,6 +410,9 @@ class SideEffectOperand extends TypedOperand {
410410
or
411411
useInstr instanceof BufferMayWriteSideEffectInstruction and
412412
result instanceof BufferMemoryAccess
413+
or
414+
useInstr instanceof ReturnIndirectionInstruction and
415+
result instanceof BufferMemoryAccess
413416
}
414417

415418
final override predicate hasMayMemoryAccess() {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ private predicate operandEscapesDomain(Operand operand) {
4949
not isArgumentForParameter(_, operand, _) and
5050
not isOnlyEscapesViaReturnArgument(operand) and
5151
not operand.getUse() instanceof ReturnValueInstruction and
52+
not operand.getUse() instanceof ReturnIndirectionInstruction and
5253
not operand instanceof PhiInputOperand
5354
}
5455

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ module InstructionSanity {
5151
opcode instanceof ReadSideEffectOpcode or
5252
opcode instanceof Opcode::InlineAsm or
5353
opcode instanceof Opcode::CallSideEffect or
54+
opcode instanceof Opcode::ReturnIndirection or
5455
opcode instanceof Opcode::AliasedUse
5556
) and
5657
tag instanceof SideEffectOperandTag
@@ -713,6 +714,14 @@ class InitializeParameterInstruction extends VariableInstruction {
713714
final override MemoryAccessKind getResultMemoryAccess() { result instanceof IndirectMemoryAccess }
714715
}
715716

717+
class InitializeIndirectionInstruction extends VariableInstruction {
718+
InitializeIndirectionInstruction() { getOpcode() instanceof Opcode::InitializeIndirection }
719+
720+
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
721+
722+
final override MemoryAccessKind getResultMemoryAccess() { result instanceof IndirectMemoryAccess }
723+
}
724+
716725
/**
717726
* An instruction that initializes the `this` pointer parameter of the enclosing function.
718727
*/
@@ -773,6 +782,18 @@ class ReturnValueInstruction extends ReturnInstruction {
773782
final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
774783
}
775784

785+
class ReturnIndirectionInstruction extends Instruction {
786+
ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
787+
788+
final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
789+
790+
final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
791+
792+
final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
793+
794+
final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
795+
}
796+
776797
class CopyInstruction extends Instruction {
777798
CopyInstruction() { getOpcode() instanceof CopyOpcode }
778799

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
@@ -410,6 +410,9 @@ class SideEffectOperand extends TypedOperand {
410410
or
411411
useInstr instanceof BufferMayWriteSideEffectInstruction and
412412
result instanceof BufferMemoryAccess
413+
or
414+
useInstr instanceof ReturnIndirectionInstruction and
415+
result instanceof BufferMemoryAccess
413416
}
414417

415418
final override predicate hasMayMemoryAccess() {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ newtype TInstructionTag =
66
InitializerVariableAddressTag() or
77
InitializerLoadStringTag() or
88
InitializerStoreTag() or
9+
InitializerIndirectAddressTag() or
10+
InitializerIndirectStoreTag() or
911
ZeroPadStringConstantTag() or
1012
ZeroPadStringElementIndexTag() or
1113
ZeroPadStringElementAddressTag() or
@@ -80,6 +82,10 @@ string getInstructionTagId(TInstructionTag tag) {
8082
or
8183
tag = InitializerUninitializedTag() and result = "InitUninit"
8284
or
85+
tag = InitializerIndirectAddressTag() and result = "InitIndirectAddr"
86+
or
87+
tag = InitializerIndirectStoreTag() and result = "InitIndirectStore"
88+
or
8389
tag = ZeroPadStringConstantTag() and result = "ZeroPadConst"
8490
or
8591
tag = ZeroPadStringElementIndexTag() and result = "ZeroPadElemIndex"

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,16 @@ newtype TTranslatedElement =
355355
translateFunction(func)
356356
)
357357
} or
358+
TTranslatedReadEffects(Function func) { translateFunction(func) } or
359+
// The read side effects in a function's return block
360+
TTranslatedReadEffect(Parameter param) {
361+
translateFunction(param.getFunction()) and
362+
exists(Type t | t = param.getUnspecifiedType() |
363+
t instanceof ArrayType or
364+
t instanceof PointerType or
365+
t instanceof ReferenceType
366+
)
367+
} or
358368
// A local declaration
359369
TTranslatedDeclarationEntry(DeclarationEntry entry) {
360370
exists(DeclStmt declStmt |

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

Lines changed: 146 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
3535
final override Function getFunction() { result = func }
3636

3737
final override TranslatedElement getChild(int id) {
38+
id = -4 and result = getReadEffects()
39+
or
3840
id = -3 and result = getConstructorInitList()
3941
or
4042
id = -2 and result = getBody()
@@ -54,6 +56,8 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
5456

5557
final private TranslatedStmt getBody() { result = getTranslatedStmt(func.getEntryPoint()) }
5658

59+
final private TranslatedReadEffects getReadEffects() { result = getTranslatedReadEffects(func) }
60+
5761
final private TranslatedParameter getParameter(int index) {
5862
result = getTranslatedParameter(func.getParameter(index))
5963
}
@@ -117,12 +121,13 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
117121
child = getBody() and
118122
result = getReturnSuccessorInstruction()
119123
or
120-
(
121-
child = getDestructorDestructionList() and
122-
if hasReturnValue()
123-
then result = getInstruction(ReturnValueAddressTag())
124-
else result = getInstruction(ReturnTag())
125-
)
124+
child = getDestructorDestructionList() and
125+
result = getReadEffects().getFirstInstruction()
126+
or
127+
child = getReadEffects() and
128+
if hasReturnValue()
129+
then result = getInstruction(ReturnValueAddressTag())
130+
else result = getInstruction(ReturnTag())
126131
}
127132

128133
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -339,6 +344,14 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
339344
result = getInstruction(InitializerStoreTag())
340345
or
341346
tag = InitializerStoreTag() and
347+
if hasIndirection()
348+
then result = getInstruction(InitializerIndirectAddressTag())
349+
else result = getParent().getChildSuccessor(this)
350+
or
351+
tag = InitializerIndirectAddressTag() and
352+
result = getInstruction(InitializerIndirectStoreTag())
353+
or
354+
tag = InitializerIndirectStoreTag() and
342355
result = getParent().getChildSuccessor(this)
343356
)
344357
}
@@ -353,12 +366,23 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
353366
tag = InitializerStoreTag() and
354367
opcode instanceof Opcode::InitializeParameter and
355368
resultType = getTypeForPRValue(getVariableType(param))
369+
or
370+
hasIndirection() and
371+
tag = InitializerIndirectAddressTag() and
372+
opcode instanceof Opcode::Load and
373+
resultType = getTypeForPRValue(getVariableType(param))
374+
or
375+
hasIndirection() and
376+
tag = InitializerIndirectStoreTag() and
377+
opcode instanceof Opcode::InitializeIndirection and
378+
resultType = getUnknownType()
356379
}
357380

358381
final override IRVariable getInstructionVariable(InstructionTag tag) {
359382
(
360383
tag = InitializerStoreTag() or
361-
tag = InitializerVariableAddressTag()
384+
tag = InitializerVariableAddressTag() or
385+
tag = InitializerIndirectStoreTag()
362386
) and
363387
result = getIRUserVariable(getFunction(), param)
364388
}
@@ -369,6 +393,28 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
369393
operandTag instanceof AddressOperandTag and
370394
result = getInstruction(InitializerVariableAddressTag())
371395
)
396+
or
397+
// this feels a little strange, but I think it's the best we can do
398+
tag = InitializerIndirectAddressTag() and
399+
(
400+
operandTag instanceof AddressOperandTag and
401+
result = getInstruction(InitializerVariableAddressTag())
402+
or
403+
operandTag instanceof LoadOperandTag and
404+
result = getInstruction(InitializerStoreTag())
405+
)
406+
or
407+
tag = InitializerIndirectStoreTag() and
408+
operandTag instanceof AddressOperandTag and
409+
result = getInstruction(InitializerIndirectAddressTag())
410+
}
411+
412+
predicate hasIndirection() {
413+
exists(Type t | t = param.getUnspecifiedType() |
414+
t instanceof ArrayType or
415+
t instanceof PointerType or
416+
t instanceof ReferenceType
417+
)
372418
}
373419
}
374420

@@ -490,3 +536,96 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
490536
)
491537
}
492538
}
539+
540+
TranslatedReadEffects getTranslatedReadEffects(Function func) { result.getAST() = func }
541+
542+
class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
543+
Function func;
544+
545+
TranslatedReadEffects() { this = TTranslatedReadEffects(func) }
546+
547+
override Locatable getAST() { result = func }
548+
549+
override Function getFunction() { result = func }
550+
551+
override string toString() { result = "read effects: " + func.toString() }
552+
553+
override TranslatedElement getChild(int id) {
554+
result = getTranslatedReadEffect(func.getParameter(id))
555+
}
556+
557+
override Instruction getFirstInstruction() {
558+
if exists(getAChild())
559+
then
560+
result = min(TranslatedReadEffect child, int id | child = getChild(id) | child order by id)
561+
.getFirstInstruction()
562+
else result = getParent().getChildSuccessor(this)
563+
}
564+
565+
override Instruction getChildSuccessor(TranslatedElement child) {
566+
exists(int id | child = getChild(id) |
567+
if exists(TranslatedReadEffect child2, int id2 | id2 > id and child2 = getChild(id2))
568+
then
569+
result = min(TranslatedReadEffect child2, int id2 |
570+
child2 = getChild(id2) and id2 > id
571+
|
572+
child2 order by id2
573+
).getFirstInstruction()
574+
else result = getParent().getChildSuccessor(this)
575+
)
576+
}
577+
578+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
579+
none()
580+
}
581+
582+
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
583+
}
584+
585+
private TranslatedReadEffect getTranslatedReadEffect(Parameter param) { result.getAST() = param }
586+
587+
class TranslatedReadEffect extends TranslatedElement, TTranslatedReadEffect {
588+
Parameter param;
589+
590+
TranslatedReadEffect() { this = TTranslatedReadEffect(param) }
591+
592+
override Locatable getAST() { result = param }
593+
594+
override string toString() { result = "read effect: " + param.toString() }
595+
596+
override TranslatedElement getChild(int id) { none() }
597+
598+
override Instruction getChildSuccessor(TranslatedElement child) { none() }
599+
600+
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind edge) {
601+
tag = OnlyInstructionTag() and
602+
edge = gotoEdge() and
603+
result = getParent().getChildSuccessor(this)
604+
}
605+
606+
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
607+
608+
override Function getFunction() { result = param.getFunction() }
609+
610+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
611+
opcode instanceof Opcode::ReturnIndirection and
612+
tag = OnlyInstructionTag() and
613+
resultType = getVoidType()
614+
}
615+
616+
final override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
617+
tag = OnlyInstructionTag() and
618+
operandTag = sideEffectOperand() and
619+
result = getTranslatedFunction(getFunction()).getUnmodeledDefinitionInstruction()
620+
or
621+
tag = OnlyInstructionTag() and
622+
operandTag = addressOperand() and
623+
result = getTranslatedParameter(param).getInstruction(InitializerIndirectAddressTag())
624+
}
625+
626+
final override CppType getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) {
627+
tag = OnlyInstructionTag() and
628+
operandTag = sideEffectOperand() and
629+
result = getUnknownType()
630+
}
631+
}

0 commit comments

Comments
 (0)