Skip to content

Commit 2356043

Browse files
author
Robert Marsh
committed
C++: add minimal AsmStmt support to IR
1 parent d741e0b commit 2356043

File tree

11 files changed

+163
-3
lines changed

11 files changed

+163
-3
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ private newtype TOpcode =
6969
TBufferWriteSideEffect() or
7070
TBufferMayWriteSideEffect() or
7171
TChi() or
72+
TInlineAsm() or
7273
TUnreached()
7374

7475
class Opcode extends TOpcode {
@@ -214,5 +215,6 @@ module Opcode {
214215
class BufferWriteSideEffect extends WriteSideEffectOpcode, BufferAccessOpcode, TBufferWriteSideEffect { override final string toString() { result = "BufferWriteSideEffect" } }
215216
class BufferMayWriteSideEffect extends MayWriteSideEffectOpcode, BufferAccessOpcode, TBufferMayWriteSideEffect { override final string toString() { result = "BufferMayWriteSideEffect" } }
216217
class Chi extends Opcode, TChi { override final string toString() { result = "Chi" } }
218+
class InlineAsm extends Opcode, TInlineAsm { override final string toString() {result = "InlineAsm" }}
217219
class Unreached extends Opcode, TUnreached { override final string toString() { result = "Unreached" } }
218220
}

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module InstructionSanity {
4040
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag or
4141
opcode instanceof Opcode::Chi and tag instanceof ChiPartialOperandTag or
4242
(
43-
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode) and
43+
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode or opcode instanceof Opcode::InlineAsm) and
4444
tag instanceof SideEffectOperandTag
4545
)
4646
)
@@ -1474,6 +1474,19 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
14741474
}
14751475
}
14761476

1477+
/**
1478+
*
1479+
*/
1480+
class InlineAsmInstruction extends Instruction {
1481+
InlineAsmInstruction() {
1482+
getOpcode() instanceof Opcode::InlineAsm
1483+
}
1484+
1485+
override final MemoryAccessKind getResultMemoryAccess() {
1486+
result instanceof EscapedMayMemoryAccess
1487+
}
1488+
}
1489+
14771490
/**
14781491
* An instruction that throws an exception.
14791492
*/

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module InstructionSanity {
4040
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag or
4141
opcode instanceof Opcode::Chi and tag instanceof ChiPartialOperandTag or
4242
(
43-
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode) and
43+
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode or opcode instanceof Opcode::InlineAsm) and
4444
tag instanceof SideEffectOperandTag
4545
)
4646
)
@@ -1474,6 +1474,19 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
14741474
}
14751475
}
14761476

1477+
/**
1478+
*
1479+
*/
1480+
class InlineAsmInstruction extends Instruction {
1481+
InlineAsmInstruction() {
1482+
getOpcode() instanceof Opcode::InlineAsm
1483+
}
1484+
1485+
override final MemoryAccessKind getResultMemoryAccess() {
1486+
result instanceof EscapedMayMemoryAccess
1487+
}
1488+
}
1489+
14771490
/**
14781491
* An instruction that throws an exception.
14791492
*/

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,3 +810,48 @@ class TranslatedSwitchStmt extends TranslatedStmt {
810810
child = getBody() and result = getParent().getChildSuccessor(this)
811811
}
812812
}
813+
814+
class TranslatedAsmStmt extends TranslatedStmt {
815+
override AsmStmt stmt;
816+
817+
override TranslatedElement getChild(int id) {
818+
none()
819+
}
820+
821+
override Instruction getFirstInstruction() {
822+
result = getInstruction(OnlyInstructionTag())
823+
}
824+
825+
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
826+
Type resultType, boolean isGLValue) {
827+
tag = OnlyInstructionTag() and
828+
opcode instanceof Opcode::InlineAsm and
829+
resultType instanceof UnknownType and
830+
isGLValue = false
831+
}
832+
833+
override Instruction getInstructionOperand(InstructionTag tag,
834+
OperandTag operandTag) {
835+
tag = OnlyInstructionTag() and
836+
operandTag instanceof SideEffectOperandTag and
837+
result = getTranslatedFunction(stmt.getEnclosingFunction()).getUnmodeledDefinitionInstruction()
838+
}
839+
840+
override final Type getInstructionOperandType(InstructionTag tag,
841+
TypedOperandTag operandTag) {
842+
tag = OnlyInstructionTag() and
843+
operandTag instanceof SideEffectOperandTag and
844+
result instanceof UnknownType
845+
}
846+
847+
override Instruction getInstructionSuccessor(InstructionTag tag,
848+
EdgeKind kind) {
849+
tag = OnlyInstructionTag() and
850+
result = getParent().getChildSuccessor(this) and
851+
kind instanceof GotoEdge
852+
}
853+
854+
override Instruction getChildSuccessor(TranslatedElement child) {
855+
none()
856+
}
857+
}

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module InstructionSanity {
4040
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag or
4141
opcode instanceof Opcode::Chi and tag instanceof ChiPartialOperandTag or
4242
(
43-
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode) and
43+
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode or opcode instanceof Opcode::InlineAsm) and
4444
tag instanceof SideEffectOperandTag
4545
)
4646
)
@@ -1474,6 +1474,19 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
14741474
}
14751475
}
14761476

1477+
/**
1478+
*
1479+
*/
1480+
class InlineAsmInstruction extends Instruction {
1481+
InlineAsmInstruction() {
1482+
getOpcode() instanceof Opcode::InlineAsm
1483+
}
1484+
1485+
override final MemoryAccessKind getResultMemoryAccess() {
1486+
result instanceof EscapedMayMemoryAccess
1487+
}
1488+
}
1489+
14771490
/**
14781491
* An instruction that throws an exception.
14791492
*/

cpp/ql/test/library-tests/ir/ir/PrintAST.expected

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7570,3 +7570,13 @@ ir.cpp:
75707570
# 1077| 0: break;
75717571
# 1079| 2: label ...:
75727572
# 1080| 3: return ...
7573+
# 1099| int AsmStmt(int)
7574+
# 1099| params:
7575+
# 1099| 0: x
7576+
# 1099| Type = int
7577+
# 1099| body: { ... }
7578+
# 1100| 0: asm statement
7579+
# 1101| 1: return ...
7580+
# 1101| 0: x
7581+
# 1101| Type = int
7582+
# 1101| ValueCategory = prvalue(load)

cpp/ql/test/library-tests/ir/ir/ir.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,4 +1096,9 @@ struct LambdaContainer {
10961096

10971097
#endif
10981098

1099+
int AsmStmt(int x) {
1100+
__asm__("");
1101+
return x;
1102+
}
1103+
10991104
// semmle-extractor-options: -std=c++17

cpp/ql/test/library-tests/ir/ir/raw_ir.expected

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4998,3 +4998,20 @@ ir.cpp:
49984998
# 1068| v10_2(void) = ReturnVoid :
49994999
# 1068| v10_3(void) = UnmodeledUse : mu*
50005000
# 1068| v10_4(void) = ExitFunction :
5001+
5002+
# 1099| int AsmStmt(int)
5003+
# 1099| Block 0
5004+
# 1099| v0_0(void) = EnterFunction :
5005+
# 1099| mu0_1(unknown) = AliasedDefinition :
5006+
# 1099| mu0_2(unknown) = UnmodeledDefinition :
5007+
# 1099| r0_3(glval<int>) = VariableAddress[x] :
5008+
# 1099| mu0_4(int) = InitializeParameter[x] : &:r0_3
5009+
# 1100| mu0_5(unknown) = InlineAsm : ~mu0_2
5010+
# 1101| r0_6(glval<int>) = VariableAddress[#return] :
5011+
# 1101| r0_7(glval<int>) = VariableAddress[x] :
5012+
# 1101| r0_8(int) = Load : &:r0_7, ~mu0_2
5013+
# 1101| mu0_9(int) = Store : &:r0_6, r0_8
5014+
# 1099| r0_10(glval<int>) = VariableAddress[#return] :
5015+
# 1099| v0_11(void) = ReturnValue : &:r0_10, ~mu0_2
5016+
# 1099| v0_12(void) = UnmodeledUse : mu*
5017+
# 1099| v0_13(void) = ExitFunction :

cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,3 +711,22 @@ ssa.cpp:
711711
# 171| v0_28(void) = ReturnVoid :
712712
# 171| v0_29(void) = UnmodeledUse : mu*
713713
# 171| v0_30(void) = ExitFunction :
714+
715+
# 179| int AsmStmt(int*)
716+
# 179| Block 0
717+
# 179| v0_0(void) = EnterFunction :
718+
# 179| m0_1(unknown) = AliasedDefinition :
719+
# 179| mu0_2(unknown) = UnmodeledDefinition :
720+
# 179| r0_3(glval<int *>) = VariableAddress[p] :
721+
# 179| m0_4(int *) = InitializeParameter[p] : &:r0_3
722+
# 180| m0_5(unknown) = InlineAsm : ~mu0_2
723+
# 180| m0_6(unknown) = Chi : total:m0_1, partial:m0_5
724+
# 181| r0_7(glval<int>) = VariableAddress[#return] :
725+
# 181| r0_8(glval<int *>) = VariableAddress[p] :
726+
# 181| r0_9(int *) = Load : &:r0_8, m0_4
727+
# 181| r0_10(int) = Load : &:r0_9, ~m0_6
728+
# 181| m0_11(int) = Store : &:r0_7, r0_10
729+
# 179| r0_12(glval<int>) = VariableAddress[#return] :
730+
# 179| v0_13(void) = ReturnValue : &:r0_12, m0_11
731+
# 179| v0_14(void) = UnmodeledUse : mu*
732+
# 179| v0_15(void) = ExitFunction :

cpp/ql/test/library-tests/ir/ssa/ssa.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,8 @@ void WrapperStruct(Wrapper w) {
175175
a = w.f; // MustExactlyOverlap
176176
x = w; // MustTotallyOverlap
177177
}
178+
179+
int AsmStmt(int *p) {
180+
__asm__("");
181+
return *p;
182+
}

0 commit comments

Comments
 (0)