Skip to content

Commit 0862004

Browse files
author
Dave Bartolomeo
authored
Merge pull request #2068 from rdmarsh2/rdmarsh/cpp/ir-constructor-side-effects
C++: side effect instrs for constructor qualifiers
2 parents 55010d0 + 0175c44 commit 0862004

27 files changed

Lines changed: 1232 additions & 797 deletions

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@ module InstructionSanity {
124124
)
125125
}
126126

127+
query predicate duplicateChiOperand(
128+
ChiInstruction chi, string message, IRFunction func, string funcText
129+
) {
130+
chi.getTotal() = chi.getPartial() and
131+
message = "Chi instruction for " + chi.getPartial().toString() +
132+
" has duplicate operands in function $@" and
133+
func = chi.getEnclosingIRFunction() and
134+
funcText = Language::getIdentityString(func.getFunction())
135+
}
136+
127137
query predicate sideEffectWithoutPrimary(
128138
SideEffectInstruction instr, string message, IRFunction func, string funcText
129139
) {

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,11 @@ private predicate hasChiNode(Alias::VirtualVariable vvar, OldInstruction def) {
396396
defLocation.getVirtualVariable() = vvar and
397397
// If the definition totally (or exactly) overlaps the virtual variable, then there's no need for a `Chi`
398398
// instruction.
399-
Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap
399+
(
400+
Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap or
401+
def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or
402+
def.getResultMemoryAccess() instanceof BufferMayMemoryAccess
403+
)
400404
)
401405
}
402406

@@ -709,7 +713,10 @@ module DefUse {
709713
defLocation = Alias::getResultMemoryLocation(def) and
710714
block.getInstruction(index) = def and
711715
overlap = Alias::getOverlap(defLocation, useLocation) and
712-
if overlap instanceof MayPartiallyOverlap
716+
if
717+
overlap instanceof MayPartiallyOverlap or
718+
def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or
719+
def.getResultMemoryAccess() instanceof BufferMayMemoryAccess
713720
then offset = (index * 2) + 1 // The use will be connected to the definition on the `Chi` instruction.
714721
else offset = index * 2 // The use will be connected to the definition on the original instruction.
715722
)

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@ module InstructionSanity {
124124
)
125125
}
126126

127+
query predicate duplicateChiOperand(
128+
ChiInstruction chi, string message, IRFunction func, string funcText
129+
) {
130+
chi.getTotal() = chi.getPartial() and
131+
message = "Chi instruction for " + chi.getPartial().toString() +
132+
" has duplicate operands in function $@" and
133+
func = chi.getEnclosingIRFunction() and
134+
funcText = Language::getIdentityString(func.getFunction())
135+
}
136+
127137
query predicate sideEffectWithoutPrimary(
128138
SideEffectInstruction instr, string message, IRFunction func, string funcText
129139
) {

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,11 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects {
352352
none()
353353
}
354354

355+
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
356+
tag = OnlyInstructionTag() and
357+
result = getTranslatedExpr(expr).getInstruction(CallTag())
358+
}
359+
355360
/**
356361
* Gets the `TranslatedFunction` containing this expression.
357362
*/
@@ -365,6 +370,39 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects {
365370
override Function getFunction() { result = expr.getEnclosingFunction() }
366371
}
367372

373+
class TranslatedStructorCallSideEffects extends TranslatedSideEffects {
374+
TranslatedStructorCallSideEffects() { getParent().(TranslatedStructorCall).hasQualifier() }
375+
376+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType t) {
377+
opcode instanceof Opcode::IndirectMayWriteSideEffect and
378+
tag instanceof OnlyInstructionTag and
379+
t = getTypeForPRValue(expr.getTarget().getDeclaringType())
380+
}
381+
382+
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
383+
(
384+
if exists(getChild(0))
385+
then result = getChild(0).getFirstInstruction()
386+
else result = getParent().getChildSuccessor(this)
387+
) and
388+
tag = OnlyInstructionTag() and
389+
kind instanceof GotoEdge
390+
}
391+
392+
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
393+
394+
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
395+
tag instanceof OnlyInstructionTag and
396+
operandTag instanceof AddressOperandTag and
397+
result = getParent().(TranslatedStructorCall).getQualifierResult()
398+
}
399+
400+
final override int getInstructionIndex(InstructionTag tag) {
401+
tag = OnlyInstructionTag() and
402+
result = -1
403+
}
404+
}
405+
368406
class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEffect {
369407
Call call;
370408
Expr arg;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ abstract class TranslatedVariableDeclaration extends TranslatedElement, Initiali
121121
private predicate hasUninitializedInstruction() {
122122
not exists(getInitialization()) or
123123
getInitialization() instanceof TranslatedListInitialization or
124+
getInitialization() instanceof TranslatedConstructorInitialization or
124125
getInitialization().(TranslatedStringLiteralInitialization).zeroInitRange(_, _)
125126
}
126127
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,8 +380,10 @@ newtype TTranslatedElement =
380380
TTranslatedAllocationSize(NewOrNewArrayExpr newExpr) { not ignoreExpr(newExpr) } or
381381
// The declaration/initialization part of a `ConditionDeclExpr`
382382
TTranslatedConditionDecl(ConditionDeclExpr expr) { not ignoreExpr(expr) } or
383-
// The side effects of a `Call` {
384-
TTranslatedSideEffects(Call expr) { exists(TTranslatedArgumentSideEffect(expr, _, _, _)) } or // A precise side effect of an argument to a `Call` {
383+
// The side effects of a `Call`
384+
TTranslatedSideEffects(Call expr) {
385+
exists(TTranslatedArgumentSideEffect(expr, _, _, _)) or expr instanceof ConstructorCall
386+
} or // A precise side effect of an argument to a `Call`
385387
TTranslatedArgumentSideEffect(Call call, Expr expr, int n, boolean isWrite) {
386388
(
387389
expr = call.getArgument(n).getFullyConverted()

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@ module InstructionSanity {
124124
)
125125
}
126126

127+
query predicate duplicateChiOperand(
128+
ChiInstruction chi, string message, IRFunction func, string funcText
129+
) {
130+
chi.getTotal() = chi.getPartial() and
131+
message = "Chi instruction for " + chi.getPartial().toString() +
132+
" has duplicate operands in function $@" and
133+
func = chi.getEnclosingIRFunction() and
134+
funcText = Language::getIdentityString(func.getFunction())
135+
}
136+
127137
query predicate sideEffectWithoutPrimary(
128138
SideEffectInstruction instr, string message, IRFunction func, string funcText
129139
) {

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,11 @@ private predicate hasChiNode(Alias::VirtualVariable vvar, OldInstruction def) {
396396
defLocation.getVirtualVariable() = vvar and
397397
// If the definition totally (or exactly) overlaps the virtual variable, then there's no need for a `Chi`
398398
// instruction.
399-
Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap
399+
(
400+
Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap or
401+
def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or
402+
def.getResultMemoryAccess() instanceof BufferMayMemoryAccess
403+
)
400404
)
401405
}
402406

@@ -709,7 +713,10 @@ module DefUse {
709713
defLocation = Alias::getResultMemoryLocation(def) and
710714
block.getInstruction(index) = def and
711715
overlap = Alias::getOverlap(defLocation, useLocation) and
712-
if overlap instanceof MayPartiallyOverlap
716+
if
717+
overlap instanceof MayPartiallyOverlap or
718+
def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or
719+
def.getResultMemoryAccess() instanceof BufferMayMemoryAccess
713720
then offset = (index * 2) + 1 // The use will be connected to the definition on the `Chi` instruction.
714721
else offset = index * 2 // The use will be connected to the definition on the original instruction.
715722
)

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ private predicate isVariableModeled(IRVariable var) {
3030
hasResultMemoryAccess(instr, var, type, bitOffset)
3131
|
3232
bitOffset = 0 and
33-
type.getIRType() = var.getIRType()
33+
type.getIRType() = var.getIRType() and
34+
not (
35+
instr.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or
36+
instr.getResultMemoryAccess() instanceof BufferMayMemoryAccess
37+
)
3438
) and
3539
forall(MemoryOperand operand, Language::LanguageType type, IntValue bitOffset |
3640
hasOperandMemoryAccess(operand, var, type, bitOffset)

cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
missingOperand
2+
| ir.cpp:809:7:809:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() |
3+
| ir.cpp:810:7:810:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() |
4+
| ir.cpp:823:7:823:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() |
5+
| ir.cpp:824:7:824:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() |
26
unexpectedOperand
37
duplicateOperand
48
missingPhiOperand
59
missingOperandType
10+
duplicateChiOperand
611
sideEffectWithoutPrimary
712
instructionWithoutSuccessor
813
ambiguousSuccessors

0 commit comments

Comments
 (0)