Skip to content

Commit 8649978

Browse files
committed
C++: add indexes for specific side effects
1 parent 24574be commit 8649978

File tree

18 files changed

+966
-784
lines changed

18 files changed

+966
-784
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,17 @@ class ConstantValueInstruction extends Instruction {
644644
final string getValue() { result = value }
645645
}
646646

647+
class IndexedInstruction extends Instruction {
648+
int index;
649+
650+
IndexedInstruction() { index = Construction::getInstructionIndex(this) }
651+
652+
653+
final override string getImmediateString() { result = index.toString() }
654+
655+
final int getIndex() { result = index }
656+
}
657+
647658
class EnterFunctionInstruction extends Instruction {
648659
EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
649660
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,11 @@ private module Cached {
342342
result = getOldInstruction(instruction).(OldIR::FieldInstruction).getField()
343343
}
344344

345+
cached
346+
int getInstructionIndex(Instruction instruction) {
347+
result = getOldInstruction(instruction).(OldIR::IndexedInstruction).getIndex()
348+
}
349+
345350
cached
346351
Function getInstructionFunction(Instruction instruction) {
347352
result = getOldInstruction(instruction).(OldIR::FunctionInstruction).getFunctionSymbol()

cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class BufferSizeOperandTag extends RegisterOperandTag, TBufferSizeOperand {
7272
final override int getSortOrder() { result = 1 }
7373
}
7474

75+
BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() }
76+
7577
/**
7678
* The operand representing the read side effect of a `SideEffectInstruction`.
7779
*/

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,17 @@ class ConstantValueInstruction extends Instruction {
644644
final string getValue() { result = value }
645645
}
646646

647+
class IndexedInstruction extends Instruction {
648+
int index;
649+
650+
IndexedInstruction() { index = Construction::getInstructionIndex(this) }
651+
652+
653+
final override string getImmediateString() { result = index.toString() }
654+
655+
final int getIndex() { result = index }
656+
}
657+
647658
class EnterFunctionInstruction extends Instruction {
648659
EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
649660
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,14 @@ private module Cached {
259259
.getInstructionConstantValue(getInstructionTag(instruction))
260260
}
261261

262+
cached
263+
int getInstructionIndex(Instruction instruction) {
264+
exists(TranslatedElement element, InstructionTag tag |
265+
instructionOrigin(instruction, element, tag) and
266+
result = element.getInstructionIndex(tag)
267+
)
268+
}
269+
262270
cached
263271
StringLiteral getInstructionStringLiteral(Instruction instruction) {
264272
result = getInstructionTranslatedElement(instruction)

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

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,12 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
456456
operandTag instanceof SideEffectOperandTag and
457457
call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(index, _) and
458458
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
459+
or
460+
tag instanceof OnlyInstructionTag and
461+
operandTag instanceof BufferSizeOperandTag and
462+
result = getTranslatedExpr(call
463+
.getArgument(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index)).getFullyConverted())
464+
.getResult()
459465
}
460466

461467
override Type getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) {
@@ -471,15 +477,26 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
471477

472478
predicate hasSpecificWriteSideEffect(Opcode op) {
473479
exists(boolean buffer, boolean mustWrite |
474-
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, buffer, mustWrite) and
475-
(
476-
buffer = true and mustWrite = false and op instanceof Opcode::BufferMayWriteSideEffect
477-
or
478-
buffer = false and mustWrite = false and op instanceof Opcode::IndirectMayWriteSideEffect
479-
or
480-
buffer = true and mustWrite = true and op instanceof Opcode::BufferMustWriteSideEffect
481-
or
482-
buffer = false and mustWrite = true and op instanceof Opcode::IndirectMustWriteSideEffect
480+
if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index))
481+
then
482+
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, true, mustWrite) and
483+
buffer = true and
484+
(
485+
mustWrite = false and op instanceof Opcode::SizedBufferMayWriteSideEffect
486+
or
487+
mustWrite = true and op instanceof Opcode::SizedBufferMustWriteSideEffect
488+
)
489+
else (
490+
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, buffer, mustWrite) and
491+
(
492+
buffer = true and mustWrite = false and op instanceof Opcode::BufferMayWriteSideEffect
493+
or
494+
buffer = false and mustWrite = false and op instanceof Opcode::IndirectMayWriteSideEffect
495+
or
496+
buffer = true and mustWrite = true and op instanceof Opcode::BufferMustWriteSideEffect
497+
or
498+
buffer = false and mustWrite = true and op instanceof Opcode::IndirectMustWriteSideEffect
499+
)
483500
)
484501
)
485502
or
@@ -495,7 +512,9 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
495512
predicate hasSpecificReadSideEffect(Opcode op) {
496513
exists(boolean buffer |
497514
call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(index, buffer) and
498-
(
515+
if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index))
516+
then buffer = true and op instanceof Opcode::SizedBufferReadSideEffect
517+
else (
499518
buffer = true and op instanceof Opcode::BufferReadSideEffect
500519
or
501520
buffer = false and op instanceof Opcode::IndirectReadSideEffect
@@ -506,6 +525,11 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
506525
op instanceof Opcode::IndirectReadSideEffect
507526
}
508527

528+
final override int getInstructionIndex(InstructionTag tag) {
529+
tag = OnlyInstructionTag() and
530+
result = index
531+
}
532+
509533
/**
510534
* Gets the `TranslatedFunction` containing this expression.
511535
*/

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,12 @@ abstract class TranslatedElement extends TTranslatedElement {
600600
*/
601601
string getInstructionConstantValue(InstructionTag tag) { none() }
602602

603+
/**
604+
* If the instruction specified by `tag` is an `IndexedInstruction`, gets the
605+
* index for that instruction.
606+
*/
607+
int getInstructionIndex(InstructionTag tag) { none() }
608+
603609
/**
604610
* If the instruction specified by `tag` is a `PointerArithmeticInstruction`,
605611
* gets the size of the type pointed to by the pointer.

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,17 @@ class ConstantValueInstruction extends Instruction {
644644
final string getValue() { result = value }
645645
}
646646

647+
class IndexedInstruction extends Instruction {
648+
int index;
649+
650+
IndexedInstruction() { index = Construction::getInstructionIndex(this) }
651+
652+
653+
final override string getImmediateString() { result = index.toString() }
654+
655+
final int getIndex() { result = index }
656+
}
657+
647658
class EnterFunctionInstruction extends Instruction {
648659
EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
649660
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,11 @@ private module Cached {
342342
result = getOldInstruction(instruction).(OldIR::FieldInstruction).getField()
343343
}
344344

345+
cached
346+
int getInstructionIndex(Instruction instruction) {
347+
result = getOldInstruction(instruction).(OldIR::IndexedInstruction).getIndex()
348+
}
349+
345350
cached
346351
Function getInstructionFunction(Instruction instruction) {
347352
result = getOldInstruction(instruction).(OldIR::FunctionInstruction).getFunctionSymbol()

cpp/ql/src/semmle/code/cpp/models/implementations/Memcpy.qll

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,12 @@ class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction
5757
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
5858
i = 1 and buffer = true
5959
}
60-
}
6160

61+
override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
62+
result = 2 and
63+
(
64+
i = 0 or
65+
i = 1
66+
)
67+
}
68+
}

0 commit comments

Comments
 (0)