C++: add minimal AsmStmt support to IR

This commit is contained in:
Robert Marsh
2019-05-28 08:26:21 -07:00
parent d741e0b20c
commit 23560436a7
11 changed files with 163 additions and 3 deletions

View File

@@ -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" } }
}

View File

@@ -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.
*/

View File

@@ -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.
*/

View File

@@ -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()
}
}

View File

@@ -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.
*/

View File

@@ -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)

View File

@@ -1096,4 +1096,9 @@ struct LambdaContainer {
#endif
int AsmStmt(int x) {
__asm__("");
return x;
}
// semmle-extractor-options: -std=c++17

View File

@@ -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 :

View File

@@ -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 :

View File

@@ -175,3 +175,8 @@ void WrapperStruct(Wrapper w) {
a = w.f; // MustExactlyOverlap
x = w; // MustTotallyOverlap
}
int AsmStmt(int *p) {
__asm__("");
return *p;
}

View File

@@ -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 :