mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
C++: hook ChiInstructions into the operand graph
This commit is contained in:
committed by
Dave Bartolomeo
parent
a33b59103a
commit
927f935e62
@@ -84,9 +84,9 @@ class PhiMemoryAccess extends MemoryAccessKind, TPhiMemoryAccess {
|
||||
* The operand is a ChiOld operand, which accesses the same memory as its
|
||||
* definition.
|
||||
*/
|
||||
class ChiOldMemoryAccess extends MemoryAccessKind, TChiOldMemoryAccess {
|
||||
class ChiTotalMemoryAccess extends MemoryAccessKind, TChiOldMemoryAccess {
|
||||
override string toString() {
|
||||
result = "chi(old)"
|
||||
result = "chi(total)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,9 +94,9 @@ class ChiOldMemoryAccess extends MemoryAccessKind, TChiOldMemoryAccess {
|
||||
* The operand is a ChiUpdate operand, which accesses the same memory as its
|
||||
* definition.
|
||||
*/
|
||||
class ChiUpdateMemoryAccess extends MemoryAccessKind, TChiUpdateMemoryAccess {
|
||||
class ChiPartialMemoryAccess extends MemoryAccessKind, TChiUpdateMemoryAccess {
|
||||
override string toString() {
|
||||
result = "chi(updated)"
|
||||
result = "chi(partial)"
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -39,6 +39,8 @@ module InstructionSanity {
|
||||
opcode instanceof Opcode::ThrowValue and tag instanceof ExceptionOperandTag or
|
||||
opcode instanceof Opcode::UnmodeledUse and tag instanceof UnmodeledUseOperandTag or
|
||||
opcode instanceof Opcode::Call and tag instanceof CallTargetOperandTag or
|
||||
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag or
|
||||
opcode instanceof Opcode::Chi and tag instanceof ChiPartialOperandTag or
|
||||
(
|
||||
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode) and
|
||||
tag instanceof SideEffectOperandTag
|
||||
@@ -1346,7 +1348,7 @@ class ChiInstruction extends Instruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
result instanceof ChiUpdateMemoryAccess
|
||||
result instanceof ChiTotalMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,9 +85,11 @@ class UnknownVirtualVariable extends VirtualVariable, TUnknownVirtualVariable {
|
||||
private newtype TMemoryAccess =
|
||||
TVariableMemoryAccess(VirtualIRVariable vvar, IntValue offset, IntValue size) {
|
||||
exists(Instruction instr |
|
||||
instr.getResultMemoryAccess() instanceof IndirectMemoryAccess and
|
||||
exists(MemoryAccessKind mak | instr.getResultMemoryAccess() = mak and not mak instanceof PhiMemoryAccess) and
|
||||
resultPointsTo(instr.getAnOperand().(AddressOperand).getDefinitionInstruction(), vvar.getIRVariable(), offset) and
|
||||
instr.getResultSize() = size
|
||||
if exists(instr.getResultSize())
|
||||
then instr.getResultSize() = size
|
||||
else size = Ints::unknown()
|
||||
)
|
||||
}
|
||||
or
|
||||
@@ -107,7 +109,7 @@ class MemoryAccess extends TMemoryAccess {
|
||||
VirtualVariable getVirtualVariable() {
|
||||
none()
|
||||
}
|
||||
|
||||
|
||||
predicate isPartialMemoryAccess() {
|
||||
none()
|
||||
}
|
||||
@@ -148,6 +150,10 @@ class VariableMemoryAccess extends TVariableMemoryAccess, MemoryAccess {
|
||||
class UnknownMemoryAccess extends TUnknownMemoryAccess, MemoryAccess {
|
||||
UnknownVirtualVariable vvar;
|
||||
|
||||
UnknownMemoryAccess() {
|
||||
this = TUnknownMemoryAccess(vvar)
|
||||
}
|
||||
|
||||
final override string toString() {
|
||||
result = vvar.toString()
|
||||
}
|
||||
@@ -201,7 +207,7 @@ Overlap getOverlap(MemoryAccess def, MemoryAccess use) {
|
||||
}
|
||||
|
||||
MemoryAccess getResultMemoryAccess(Instruction instr) {
|
||||
instr.getResultMemoryAccess() instanceof IndirectMemoryAccess and
|
||||
exists(instr.getResultMemoryAccess()) and
|
||||
if exists(IRVariable var, IntValue i |
|
||||
resultPointsTo(instr.getAnOperand().(AddressOperand).getDefinitionInstruction(), var, i)
|
||||
)
|
||||
@@ -214,13 +220,13 @@ MemoryAccess getResultMemoryAccess(Instruction instr) {
|
||||
}
|
||||
|
||||
MemoryAccess getOperandMemoryAccess(Operand operand) {
|
||||
operand.getMemoryAccess() instanceof IndirectMemoryAccess and
|
||||
exists(operand.getMemoryAccess()) and
|
||||
if exists(IRVariable var, IntValue i |
|
||||
resultPointsTo(operand.getAddressOperand().getDefinitionInstruction(), var, i)
|
||||
)
|
||||
then exists(IRVariable var, IntValue i |
|
||||
resultPointsTo(operand.getAddressOperand().getDefinitionInstruction(), var, i) and
|
||||
result = getVariableMemoryAccess(var, i, operand.getAddressOperand().getDefinitionInstruction().getResultSize())
|
||||
result = getVariableMemoryAccess(var, i, operand.getDefinitionInstruction().getResultSize())
|
||||
)
|
||||
else
|
||||
result = TUnknownMemoryAccess(TUnknownVirtualVariable(operand.getInstruction().getFunctionIR()))
|
||||
|
||||
@@ -149,11 +149,11 @@ cached private module Cached {
|
||||
hasUseAtRank(vvar, useBlock, useRank, oldInstruction) and
|
||||
definitionReachesUse(vvar, defBlock, defRank, useBlock, useRank) and
|
||||
if defIndex >= 0 then
|
||||
result = getNewInstruction(defBlock.getInstruction(defIndex))
|
||||
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
|
||||
else
|
||||
result = getPhiInstruction(instruction.getFunction(), defBlock, vvar)
|
||||
result = getPhiInstruction(instruction.getFunction(), defBlock, vvar)
|
||||
)
|
||||
)
|
||||
)
|
||||
else (
|
||||
result = instruction.getFunctionIR().getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
@@ -168,9 +168,13 @@ cached private module Cached {
|
||||
result = getNewInstruction(oldDefinition)
|
||||
)
|
||||
)
|
||||
else
|
||||
else
|
||||
result = getNewInstruction(oldOperand.getDefinitionInstruction())
|
||||
)
|
||||
) or
|
||||
instruction.getTag() = ChiTag(getOldInstruction(result)) and
|
||||
tag instanceof ChiPartialOperandTag
|
||||
or
|
||||
result = getChiInstructionTotalOperand(instruction.(ChiInstruction), tag.(ChiTotalOperandTag))
|
||||
}
|
||||
|
||||
cached Instruction getPhiInstructionOperandDefinition(PhiInstruction instr,
|
||||
@@ -184,12 +188,24 @@ cached private module Cached {
|
||||
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
|
||||
definitionReachesEndOfBlock(vvar, defBlock, defRank, predBlock) and
|
||||
if defIndex >= 0 then
|
||||
result = getNewInstruction(defBlock.getInstruction(defIndex))
|
||||
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
|
||||
else
|
||||
result = getPhiInstruction(instr.getFunction(), defBlock, vvar)
|
||||
)
|
||||
}
|
||||
|
||||
cached Instruction getChiInstructionTotalOperand(ChiInstruction chiInstr, ChiTotalOperandTag tag) {
|
||||
exists(Alias::VirtualVariable vvar, OldIR::Instruction oldInstr, OldIR::IRBlock defBlock,
|
||||
int defRank, int defIndex, OldIR::IRBlock useBlock, int useRank |
|
||||
ChiTag(oldInstr) = chiInstr.getTag() and
|
||||
vvar = Alias::getResultMemoryAccess(oldInstr).getVirtualVariable() and
|
||||
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
|
||||
hasUseAtRank(vvar, useBlock, useRank, oldInstr) and
|
||||
definitionReachesUse(vvar, defBlock, defRank, useBlock, useRank) and
|
||||
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
|
||||
)
|
||||
}
|
||||
|
||||
cached Instruction getPhiInstructionBlockStart(PhiInstruction instr) {
|
||||
exists(OldIR::IRBlock oldBlock |
|
||||
instr.getTag() = PhiTag(_, oldBlock) and
|
||||
@@ -300,7 +316,12 @@ cached private module Cached {
|
||||
private predicate hasUse(Alias::VirtualVariable vvar,
|
||||
OldIR::Instruction use, OldIR::IRBlock block, int index) {
|
||||
exists(Alias::MemoryAccess access |
|
||||
access = Alias::getOperandMemoryAccess(use.getAnOperand()) and
|
||||
(
|
||||
access = Alias::getOperandMemoryAccess(use.getAnOperand())
|
||||
or
|
||||
access = Alias::getResultMemoryAccess(use) and
|
||||
access.isPartialMemoryAccess()
|
||||
) and
|
||||
block.getInstruction(index) = use and
|
||||
vvar = access.getVirtualVariable()
|
||||
)
|
||||
@@ -438,7 +459,8 @@ cached private module Cached {
|
||||
ma = Alias::getResultMemoryAccess(def) and
|
||||
ma.isPartialMemoryAccess() and
|
||||
ma.getVirtualVariable() = vvar
|
||||
)
|
||||
) and
|
||||
not def instanceof OldIR::UnmodeledDefinitionInstruction
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ module InstructionSanity {
|
||||
opcode instanceof Opcode::ThrowValue and tag instanceof ExceptionOperandTag or
|
||||
opcode instanceof Opcode::UnmodeledUse and tag instanceof UnmodeledUseOperandTag or
|
||||
opcode instanceof Opcode::Call and tag instanceof CallTargetOperandTag or
|
||||
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag or
|
||||
opcode instanceof Opcode::Chi and tag instanceof ChiPartialOperandTag or
|
||||
(
|
||||
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode) and
|
||||
tag instanceof SideEffectOperandTag
|
||||
@@ -1346,7 +1348,7 @@ class ChiInstruction extends Instruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
result instanceof ChiUpdateMemoryAccess
|
||||
result instanceof ChiTotalMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ module InstructionSanity {
|
||||
opcode instanceof Opcode::ThrowValue and tag instanceof ExceptionOperandTag or
|
||||
opcode instanceof Opcode::UnmodeledUse and tag instanceof UnmodeledUseOperandTag or
|
||||
opcode instanceof Opcode::Call and tag instanceof CallTargetOperandTag or
|
||||
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag or
|
||||
opcode instanceof Opcode::Chi and tag instanceof ChiPartialOperandTag or
|
||||
(
|
||||
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode) and
|
||||
tag instanceof SideEffectOperandTag
|
||||
@@ -1346,7 +1348,7 @@ class ChiInstruction extends Instruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
result instanceof ChiUpdateMemoryAccess
|
||||
result instanceof ChiTotalMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -149,9 +149,9 @@ cached private module Cached {
|
||||
hasUseAtRank(vvar, useBlock, useRank, oldInstruction) and
|
||||
definitionReachesUse(vvar, defBlock, defRank, useBlock, useRank) and
|
||||
if defIndex >= 0 then
|
||||
result = getNewInstruction(defBlock.getInstruction(defIndex))
|
||||
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
|
||||
else
|
||||
result = getPhiInstruction(instruction.getFunction(), defBlock, vvar)
|
||||
result = getPhiInstruction(instruction.getFunction(), defBlock, vvar)
|
||||
)
|
||||
)
|
||||
else (
|
||||
@@ -170,7 +170,11 @@ cached private module Cached {
|
||||
)
|
||||
else
|
||||
result = getNewInstruction(oldOperand.getDefinitionInstruction())
|
||||
)
|
||||
) or
|
||||
instruction.getTag() = ChiTag(getOldInstruction(result)) and
|
||||
tag instanceof ChiPartialOperandTag
|
||||
or
|
||||
result = getChiInstructionTotalOperand(instruction.(ChiInstruction), tag.(ChiTotalOperandTag))
|
||||
}
|
||||
|
||||
cached Instruction getPhiInstructionOperandDefinition(PhiInstruction instr,
|
||||
@@ -184,12 +188,24 @@ cached private module Cached {
|
||||
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
|
||||
definitionReachesEndOfBlock(vvar, defBlock, defRank, predBlock) and
|
||||
if defIndex >= 0 then
|
||||
result = getNewInstruction(defBlock.getInstruction(defIndex))
|
||||
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
|
||||
else
|
||||
result = getPhiInstruction(instr.getFunction(), defBlock, vvar)
|
||||
)
|
||||
}
|
||||
|
||||
cached Instruction getChiInstructionTotalOperand(ChiInstruction chiInstr, ChiTotalOperandTag tag) {
|
||||
exists(Alias::VirtualVariable vvar, OldIR::Instruction oldInstr, OldIR::IRBlock defBlock,
|
||||
int defRank, int defIndex, OldIR::IRBlock useBlock, int useRank |
|
||||
ChiTag(oldInstr) = chiInstr.getTag() and
|
||||
vvar = Alias::getResultMemoryAccess(oldInstr).getVirtualVariable() and
|
||||
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
|
||||
hasUseAtRank(vvar, useBlock, useRank, oldInstr) and
|
||||
definitionReachesUse(vvar, defBlock, defRank, useBlock, useRank) and
|
||||
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
|
||||
)
|
||||
}
|
||||
|
||||
cached Instruction getPhiInstructionBlockStart(PhiInstruction instr) {
|
||||
exists(OldIR::IRBlock oldBlock |
|
||||
instr.getTag() = PhiTag(_, oldBlock) and
|
||||
@@ -300,7 +316,12 @@ cached private module Cached {
|
||||
private predicate hasUse(Alias::VirtualVariable vvar,
|
||||
OldIR::Instruction use, OldIR::IRBlock block, int index) {
|
||||
exists(Alias::MemoryAccess access |
|
||||
access = Alias::getOperandMemoryAccess(use.getAnOperand()) and
|
||||
(
|
||||
access = Alias::getOperandMemoryAccess(use.getAnOperand())
|
||||
or
|
||||
access = Alias::getResultMemoryAccess(use) and
|
||||
access.isPartialMemoryAccess()
|
||||
) and
|
||||
block.getInstruction(index) = use and
|
||||
vvar = access.getVirtualVariable()
|
||||
)
|
||||
@@ -438,7 +459,8 @@ cached private module Cached {
|
||||
ma = Alias::getResultMemoryAccess(def) and
|
||||
ma.isPartialMemoryAccess() and
|
||||
ma.getVirtualVariable() = vvar
|
||||
)
|
||||
) and
|
||||
not def instanceof OldIR::UnmodeledDefinitionInstruction
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ private newtype TOperandTag =
|
||||
exists(op.getChild(argIndex))
|
||||
)
|
||||
} or
|
||||
TChiOldOperand() or
|
||||
TChiUpdateOperand()
|
||||
TChiTotalOperand() or
|
||||
TChiPartialOperand()
|
||||
|
||||
/**
|
||||
* Identifies the kind of operand on an instruction. Each `Instruction` has at
|
||||
@@ -315,9 +315,9 @@ PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
|
||||
result = TPositionalArgumentOperand(argIndex)
|
||||
}
|
||||
|
||||
class ChiOldOperand extends OperandTag, TChiOldOperand {
|
||||
class ChiTotalOperandTag extends OperandTag, TChiTotalOperand {
|
||||
override final string toString() {
|
||||
result = "ChiOld"
|
||||
result = "ChiTotal"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
@@ -325,9 +325,9 @@ class ChiOldOperand extends OperandTag, TChiOldOperand {
|
||||
}
|
||||
}
|
||||
|
||||
class ChiUpdateOperand extends OperandTag, TChiUpdateOperand {
|
||||
class ChiPartialOperandTag extends OperandTag, TChiPartialOperand {
|
||||
override final string toString() {
|
||||
result = "ChiUpdate"
|
||||
result = "ChiPartial"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
| constant_func.cpp:1:5:1:18 | IR: ReturnConstant | 7 |
|
||||
| constant_func.cpp:5:5:5:21 | IR: ReturnConstantPhi | 7 |
|
||||
| constant_func.cpp:25:5:25:25 | IR: ReturnConstantPhiLoop | 7 |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,18 @@
|
||||
missingOperand
|
||||
| ir.cpp:174:9:174:12 | Load: access to array | CopySource |
|
||||
| ir.cpp:175:9:175:12 | Load: access to array | CopySource |
|
||||
| ir.cpp:188:14:188:21 | Load: access to array | CopySource |
|
||||
| ir.cpp:190:18:190:23 | Load: access to array | CopySource |
|
||||
| ir.cpp:572:22:572:23 | Load: | CopySource |
|
||||
| ir.cpp:676:12:676:12 | Load: (reference dereference) | CopySource |
|
||||
| ir.cpp:894:14:894:43 | Load: __builtin_va_arg | CopySource |
|
||||
| ir.cpp:895:30:895:33 | Load: __builtin_va_arg | CopySource |
|
||||
| ir.cpp:265:6:265:14 | UnmodeledUse: For_Empty | UnmodeledUse |
|
||||
| ir.cpp:272:6:272:13 | UnmodeledUse: For_Init | UnmodeledUse |
|
||||
| ir.cpp:285:6:285:15 | UnmodeledUse: For_Update | UnmodeledUse |
|
||||
| ir.cpp:298:6:298:19 | UnmodeledUse: For_InitUpdate | UnmodeledUse |
|
||||
| ir.cpp:504:19:504:19 | Chi: x | ChiTotal |
|
||||
| ir.cpp:505:19:505:19 | Chi: x | ChiTotal |
|
||||
| ir.cpp:506:16:506:18 | Chi: {...} | ChiTotal |
|
||||
| ir.cpp:513:14:513:16 | Chi: {...} | ChiTotal |
|
||||
| ir.cpp:514:19:514:19 | Chi: x | ChiTotal |
|
||||
| ir.cpp:515:19:515:19 | Chi: x | ChiTotal |
|
||||
| ir.cpp:516:19:516:19 | Chi: x | ChiTotal |
|
||||
| ir.cpp:736:5:736:19 | Chi: call to String | ChiTotal |
|
||||
| ir.cpp:962:26:962:30 | Chi: 10002 | ChiTotal |
|
||||
| ir.cpp:962:41:962:45 | Chi: 10900 | ChiTotal |
|
||||
unexpectedOperand
|
||||
duplicateOperand
|
||||
missingPhiOperand
|
||||
|
||||
Reference in New Issue
Block a user