mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
C++: Treat asmStmt operands as input/output in IR
This commit is contained in:
@@ -73,7 +73,8 @@ module InstructionSanity {
|
||||
operand.getOperandTag() = tag) and
|
||||
not expectsOperand(instr, tag) and
|
||||
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
|
||||
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag)
|
||||
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag) and
|
||||
not (instr instanceof InlineAsmInstruction and tag instanceof AsmOperandTag)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -73,7 +73,8 @@ module InstructionSanity {
|
||||
operand.getOperandTag() = tag) and
|
||||
not expectsOperand(instr, tag) and
|
||||
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
|
||||
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag)
|
||||
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag) and
|
||||
not (instr instanceof InlineAsmInstruction and tag instanceof AsmOperandTag)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -84,7 +84,13 @@ newtype TInstructionTag =
|
||||
} or
|
||||
InitializerElementDefaultValueStoreTag(int elementIndex) {
|
||||
elementIsInitialized(elementIndex)
|
||||
}
|
||||
} or
|
||||
AsmTag() or
|
||||
AsmInputTag(int elementIndex) {
|
||||
exists(AsmStmt asm |
|
||||
exists(asm.getChild(elementIndex))
|
||||
)
|
||||
}
|
||||
|
||||
class InstructionTag extends TInstructionTag {
|
||||
final string toString() {
|
||||
@@ -161,5 +167,9 @@ string getInstructionTagId(TInstructionTag tag) {
|
||||
tag = InitializerElementDefaultValueStoreTag(index) and tagName = "InitElemDefValStore"
|
||||
) and
|
||||
result = tagName + "(" + index + ")"
|
||||
) or
|
||||
tag = AsmTag() and result = "Asm" or
|
||||
exists(int index |
|
||||
tag = AsmInputTag(index) and result = "AsmInputTag(" + index + ")"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
||||
// represent them.
|
||||
newExpr.getInitializer().getFullyConverted() = expr
|
||||
) or
|
||||
// Ignore descendants of asm statements, since we can't differentiate inputs and outputs
|
||||
// Do not translate input/output variables in GNU asm statements
|
||||
getRealParent(expr) instanceof AsmStmt or
|
||||
ignoreExprAndDescendants(getRealParent(expr)) // recursive case
|
||||
}
|
||||
|
||||
@@ -819,36 +819,69 @@ class TranslatedAsmStmt extends TranslatedStmt {
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction() {
|
||||
result = getInstruction(OnlyInstructionTag())
|
||||
if exists(stmt.getChild(0))
|
||||
then result = getInstruction(AsmInputTag(0))
|
||||
else result = getInstruction(AsmTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
|
||||
Type resultType, boolean isGLValue) {
|
||||
tag = OnlyInstructionTag() and
|
||||
tag = AsmTag() and
|
||||
opcode instanceof Opcode::InlineAsm and
|
||||
resultType instanceof UnknownType and
|
||||
isGLValue = false
|
||||
or
|
||||
exists(int index, VariableAccess va |
|
||||
tag = AsmInputTag(index) and
|
||||
stmt.getChild(index) = va and
|
||||
opcode instanceof Opcode::VariableAddress and
|
||||
resultType = va.getType().getUnspecifiedType() and
|
||||
isGLValue = true
|
||||
)
|
||||
}
|
||||
|
||||
override IRVariable getInstructionVariable(InstructionTag tag) {
|
||||
exists(int index |
|
||||
tag = AsmInputTag(index) and
|
||||
result = getIRUserVariable(stmt.getEnclosingFunction(), stmt.getChild(index).(VariableAccess).getTarget())
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getInstructionOperand(InstructionTag tag,
|
||||
OperandTag operandTag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
tag = AsmTag() and
|
||||
operandTag instanceof SideEffectOperandTag and
|
||||
result = getTranslatedFunction(stmt.getEnclosingFunction()).getUnmodeledDefinitionInstruction()
|
||||
or
|
||||
exists(int index |
|
||||
tag = AsmTag() and
|
||||
operandTag = asmOperand(index) and
|
||||
result = getInstruction(AsmInputTag(index))
|
||||
)
|
||||
}
|
||||
|
||||
override final Type getInstructionOperandType(InstructionTag tag,
|
||||
TypedOperandTag operandTag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
tag = AsmTag() and
|
||||
operandTag instanceof SideEffectOperandTag and
|
||||
result instanceof UnknownType
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag,
|
||||
EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
tag = AsmTag() and
|
||||
result = getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
or
|
||||
exists(int index |
|
||||
tag = AsmInputTag(index) and
|
||||
kind instanceof GotoEdge and
|
||||
if exists(stmt.getChild(index + 1))
|
||||
then
|
||||
result = getInstruction(AsmInputTag(index + 1))
|
||||
else
|
||||
result = getInstruction(AsmTag())
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
|
||||
@@ -73,7 +73,8 @@ module InstructionSanity {
|
||||
operand.getOperandTag() = tag) and
|
||||
not expectsOperand(instr, tag) and
|
||||
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
|
||||
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag)
|
||||
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag) and
|
||||
not (instr instanceof InlineAsmInstruction and tag instanceof AsmOperandTag)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,12 @@ private newtype TOperandTag =
|
||||
)
|
||||
} or
|
||||
TChiTotalOperand() or
|
||||
TChiPartialOperand()
|
||||
TChiPartialOperand() or
|
||||
TAsmOperand(int index) {
|
||||
exists(AsmStmt asm |
|
||||
exists(asm.getChild(index))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies the kind of operand on an instruction. Each `Instruction` has at
|
||||
@@ -362,3 +367,27 @@ class ChiPartialOperandTag extends MemoryOperandTag, TChiPartialOperand {
|
||||
ChiPartialOperandTag chiPartialOperand() {
|
||||
result = TChiPartialOperand()
|
||||
}
|
||||
|
||||
class AsmOperandTag extends RegisterOperandTag, TAsmOperand {
|
||||
int index;
|
||||
|
||||
AsmOperandTag() {
|
||||
this = TAsmOperand(index)
|
||||
}
|
||||
|
||||
override final string toString() {
|
||||
result = "AsmOperand(" + index + ")"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 15 + index
|
||||
}
|
||||
|
||||
override final string getLabel() {
|
||||
result = index.toString() + ":"
|
||||
}
|
||||
}
|
||||
|
||||
AsmOperandTag asmOperand(int index) {
|
||||
result = TAsmOperand(index)
|
||||
}
|
||||
Reference in New Issue
Block a user