mirror of
https://github.com/github/codeql.git
synced 2026-05-02 20:25:13 +02:00
C++: add minimal AsmStmt support to IR
This commit is contained in:
@@ -69,6 +69,7 @@ private newtype TOpcode =
|
||||
TBufferWriteSideEffect() or
|
||||
TBufferMayWriteSideEffect() or
|
||||
TChi() or
|
||||
TInlineAsm() or
|
||||
TUnreached()
|
||||
|
||||
class Opcode extends TOpcode {
|
||||
@@ -214,5 +215,6 @@ module Opcode {
|
||||
class BufferWriteSideEffect extends WriteSideEffectOpcode, BufferAccessOpcode, TBufferWriteSideEffect { override final string toString() { result = "BufferWriteSideEffect" } }
|
||||
class BufferMayWriteSideEffect extends MayWriteSideEffectOpcode, BufferAccessOpcode, TBufferMayWriteSideEffect { override final string toString() { result = "BufferMayWriteSideEffect" } }
|
||||
class Chi extends Opcode, TChi { override final string toString() { result = "Chi" } }
|
||||
class InlineAsm extends Opcode, TInlineAsm { override final string toString() {result = "InlineAsm" }}
|
||||
class Unreached extends Opcode, TUnreached { override final string toString() { result = "Unreached" } }
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ module InstructionSanity {
|
||||
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
|
||||
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode or opcode instanceof Opcode::InlineAsm) and
|
||||
tag instanceof SideEffectOperandTag
|
||||
)
|
||||
)
|
||||
@@ -1474,6 +1474,19 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class InlineAsmInstruction extends Instruction {
|
||||
InlineAsmInstruction() {
|
||||
getOpcode() instanceof Opcode::InlineAsm
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that throws an exception.
|
||||
*/
|
||||
|
||||
@@ -40,7 +40,7 @@ module InstructionSanity {
|
||||
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
|
||||
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode or opcode instanceof Opcode::InlineAsm) and
|
||||
tag instanceof SideEffectOperandTag
|
||||
)
|
||||
)
|
||||
@@ -1474,6 +1474,19 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class InlineAsmInstruction extends Instruction {
|
||||
InlineAsmInstruction() {
|
||||
getOpcode() instanceof Opcode::InlineAsm
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that throws an exception.
|
||||
*/
|
||||
|
||||
@@ -810,3 +810,48 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
child = getBody() and result = getParent().getChildSuccessor(this)
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedAsmStmt extends TranslatedStmt {
|
||||
override AsmStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction() {
|
||||
result = getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
|
||||
Type resultType, boolean isGLValue) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::InlineAsm and
|
||||
resultType instanceof UnknownType and
|
||||
isGLValue = false
|
||||
}
|
||||
|
||||
override Instruction getInstructionOperand(InstructionTag tag,
|
||||
OperandTag operandTag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
operandTag instanceof SideEffectOperandTag and
|
||||
result = getTranslatedFunction(stmt.getEnclosingFunction()).getUnmodeledDefinitionInstruction()
|
||||
}
|
||||
|
||||
override final Type getInstructionOperandType(InstructionTag tag,
|
||||
TypedOperandTag operandTag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
operandTag instanceof SideEffectOperandTag and
|
||||
result instanceof UnknownType
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag,
|
||||
EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ module InstructionSanity {
|
||||
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
|
||||
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode or opcode instanceof Opcode::InlineAsm) and
|
||||
tag instanceof SideEffectOperandTag
|
||||
)
|
||||
)
|
||||
@@ -1474,6 +1474,19 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class InlineAsmInstruction extends Instruction {
|
||||
InlineAsmInstruction() {
|
||||
getOpcode() instanceof Opcode::InlineAsm
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
result instanceof EscapedMayMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that throws an exception.
|
||||
*/
|
||||
|
||||
@@ -7570,3 +7570,13 @@ ir.cpp:
|
||||
# 1077| 0: break;
|
||||
# 1079| 2: label ...:
|
||||
# 1080| 3: return ...
|
||||
# 1099| int AsmStmt(int)
|
||||
# 1099| params:
|
||||
# 1099| 0: x
|
||||
# 1099| Type = int
|
||||
# 1099| body: { ... }
|
||||
# 1100| 0: asm statement
|
||||
# 1101| 1: return ...
|
||||
# 1101| 0: x
|
||||
# 1101| Type = int
|
||||
# 1101| ValueCategory = prvalue(load)
|
||||
|
||||
@@ -1096,4 +1096,9 @@ struct LambdaContainer {
|
||||
|
||||
#endif
|
||||
|
||||
int AsmStmt(int x) {
|
||||
__asm__("");
|
||||
return x;
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++17
|
||||
|
||||
@@ -4998,3 +4998,20 @@ ir.cpp:
|
||||
# 1068| v10_2(void) = ReturnVoid :
|
||||
# 1068| v10_3(void) = UnmodeledUse : mu*
|
||||
# 1068| v10_4(void) = ExitFunction :
|
||||
|
||||
# 1099| int AsmStmt(int)
|
||||
# 1099| Block 0
|
||||
# 1099| v0_0(void) = EnterFunction :
|
||||
# 1099| mu0_1(unknown) = AliasedDefinition :
|
||||
# 1099| mu0_2(unknown) = UnmodeledDefinition :
|
||||
# 1099| r0_3(glval<int>) = VariableAddress[x] :
|
||||
# 1099| mu0_4(int) = InitializeParameter[x] : &:r0_3
|
||||
# 1100| mu0_5(unknown) = InlineAsm : ~mu0_2
|
||||
# 1101| r0_6(glval<int>) = VariableAddress[#return] :
|
||||
# 1101| r0_7(glval<int>) = VariableAddress[x] :
|
||||
# 1101| r0_8(int) = Load : &:r0_7, ~mu0_2
|
||||
# 1101| mu0_9(int) = Store : &:r0_6, r0_8
|
||||
# 1099| r0_10(glval<int>) = VariableAddress[#return] :
|
||||
# 1099| v0_11(void) = ReturnValue : &:r0_10, ~mu0_2
|
||||
# 1099| v0_12(void) = UnmodeledUse : mu*
|
||||
# 1099| v0_13(void) = ExitFunction :
|
||||
|
||||
@@ -711,3 +711,22 @@ ssa.cpp:
|
||||
# 171| v0_28(void) = ReturnVoid :
|
||||
# 171| v0_29(void) = UnmodeledUse : mu*
|
||||
# 171| v0_30(void) = ExitFunction :
|
||||
|
||||
# 179| int AsmStmt(int*)
|
||||
# 179| Block 0
|
||||
# 179| v0_0(void) = EnterFunction :
|
||||
# 179| m0_1(unknown) = AliasedDefinition :
|
||||
# 179| mu0_2(unknown) = UnmodeledDefinition :
|
||||
# 179| r0_3(glval<int *>) = VariableAddress[p] :
|
||||
# 179| m0_4(int *) = InitializeParameter[p] : &:r0_3
|
||||
# 180| m0_5(unknown) = InlineAsm : ~mu0_2
|
||||
# 180| m0_6(unknown) = Chi : total:m0_1, partial:m0_5
|
||||
# 181| r0_7(glval<int>) = VariableAddress[#return] :
|
||||
# 181| r0_8(glval<int *>) = VariableAddress[p] :
|
||||
# 181| r0_9(int *) = Load : &:r0_8, m0_4
|
||||
# 181| r0_10(int) = Load : &:r0_9, ~m0_6
|
||||
# 181| m0_11(int) = Store : &:r0_7, r0_10
|
||||
# 179| r0_12(glval<int>) = VariableAddress[#return] :
|
||||
# 179| v0_13(void) = ReturnValue : &:r0_12, m0_11
|
||||
# 179| v0_14(void) = UnmodeledUse : mu*
|
||||
# 179| v0_15(void) = ExitFunction :
|
||||
|
||||
@@ -175,3 +175,8 @@ void WrapperStruct(Wrapper w) {
|
||||
a = w.f; // MustExactlyOverlap
|
||||
x = w; // MustTotallyOverlap
|
||||
}
|
||||
|
||||
int AsmStmt(int *p) {
|
||||
__asm__("");
|
||||
return *p;
|
||||
}
|
||||
|
||||
@@ -683,3 +683,21 @@ ssa.cpp:
|
||||
# 171| v0_28(void) = ReturnVoid :
|
||||
# 171| v0_29(void) = UnmodeledUse : mu*
|
||||
# 171| v0_30(void) = ExitFunction :
|
||||
|
||||
# 179| int AsmStmt(int*)
|
||||
# 179| Block 0
|
||||
# 179| v0_0(void) = EnterFunction :
|
||||
# 179| mu0_1(unknown) = AliasedDefinition :
|
||||
# 179| mu0_2(unknown) = UnmodeledDefinition :
|
||||
# 179| r0_3(glval<int *>) = VariableAddress[p] :
|
||||
# 179| m0_4(int *) = InitializeParameter[p] : &:r0_3
|
||||
# 180| mu0_5(unknown) = InlineAsm : ~mu0_2
|
||||
# 181| r0_6(glval<int>) = VariableAddress[#return] :
|
||||
# 181| r0_7(glval<int *>) = VariableAddress[p] :
|
||||
# 181| r0_8(int *) = Load : &:r0_7, m0_4
|
||||
# 181| r0_9(int) = Load : &:r0_8, ~mu0_2
|
||||
# 181| m0_10(int) = Store : &:r0_6, r0_9
|
||||
# 179| r0_11(glval<int>) = VariableAddress[#return] :
|
||||
# 179| v0_12(void) = ReturnValue : &:r0_11, m0_10
|
||||
# 179| v0_13(void) = UnmodeledUse : mu*
|
||||
# 179| v0_14(void) = ExitFunction :
|
||||
|
||||
Reference in New Issue
Block a user