mirror of
https://github.com/github/codeql.git
synced 2026-04-23 15:55:18 +02:00
Merge pull request #19775 from jketema/seh-2
C++: Generate SEH edges for pointer dereference loads/stores in `__try` blocks
This commit is contained in:
@@ -381,6 +381,14 @@ abstract class TranslatedValueCategoryAdjustment extends TranslatedExpr {
|
||||
final TranslatedCoreExpr getOperand() { result.getExpr() = expr }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `expr` requires an `SehExceptionEdge` to be generated.
|
||||
*/
|
||||
private predicate hasSehExceptionEdge(Expr expr) {
|
||||
expr instanceof PointerDereferenceExpr and
|
||||
exists(MicrosoftTryStmt tryStmt | tryStmt.getStmt() = expr.getEnclosingStmt().getParent*())
|
||||
}
|
||||
|
||||
/**
|
||||
* IR translation of an implicit lvalue-to-rvalue conversion on the result of
|
||||
* an expression.
|
||||
@@ -400,7 +408,13 @@ class TranslatedLoad extends TranslatedValueCategoryAdjustment, TTranslatedLoad
|
||||
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = LoadTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
(
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
or
|
||||
hasSehExceptionEdge(expr) and
|
||||
kind instanceof SehExceptionEdge and
|
||||
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge e))
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
@@ -1945,7 +1959,13 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr {
|
||||
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = AssignmentStoreTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
(
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
or
|
||||
hasSehExceptionEdge(expr.getLValue()) and
|
||||
kind instanceof SehExceptionEdge and
|
||||
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge e))
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
|
||||
@@ -49689,6 +49689,74 @@ try_except.c:
|
||||
# 52| Type = [IntType] int
|
||||
# 52| ValueCategory = prvalue(load)
|
||||
# 54| getStmt(2): [ReturnStmt] return ...
|
||||
# 56| [TopLevelFunction] void k(int*, int*, int*)
|
||||
# 56| <params>:
|
||||
# 56| getParameter(0): [Parameter] b
|
||||
# 56| Type = [IntPointerType] int *
|
||||
# 56| getParameter(1): [Parameter] c
|
||||
# 56| Type = [IntPointerType] int *
|
||||
# 56| getParameter(2): [Parameter] d
|
||||
# 56| Type = [IntPointerType] int *
|
||||
# 56| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 57| getStmt(0): [DeclStmt] declaration
|
||||
# 57| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
|
||||
# 57| Type = [IntType] int
|
||||
# 57| getVariable().getInitializer(): [Initializer] initializer for x
|
||||
# 57| getExpr(): [Literal] 0
|
||||
# 57| Type = [IntType] int
|
||||
# 57| Value = [Literal] 0
|
||||
# 57| ValueCategory = prvalue
|
||||
# 58| getStmt(1): [MicrosoftTryExceptStmt] __try { ... } __except( ... ) { ... }
|
||||
# 58| getStmt(): [BlockStmt] { ... }
|
||||
# 59| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 59| getExpr(): [AssignExpr] ... = ...
|
||||
# 59| Type = [IntType] int
|
||||
# 59| ValueCategory = prvalue
|
||||
# 59| getLValue(): [VariableAccess] x
|
||||
# 59| Type = [IntType] int
|
||||
# 59| ValueCategory = lvalue
|
||||
# 59| getRValue(): [PointerDereferenceExpr] * ...
|
||||
# 59| Type = [IntType] int
|
||||
# 59| ValueCategory = prvalue(load)
|
||||
# 59| getOperand(): [VariableAccess] b
|
||||
# 59| Type = [IntPointerType] int *
|
||||
# 59| ValueCategory = prvalue(load)
|
||||
# 60| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 60| getExpr(): [AssignExpr] ... = ...
|
||||
# 60| Type = [IntType] int
|
||||
# 60| ValueCategory = prvalue
|
||||
# 60| getLValue(): [PointerDereferenceExpr] * ...
|
||||
# 60| Type = [IntType] int
|
||||
# 60| ValueCategory = lvalue
|
||||
# 60| getOperand(): [VariableAccess] c
|
||||
# 60| Type = [IntPointerType] int *
|
||||
# 60| ValueCategory = prvalue(load)
|
||||
# 60| getRValue(): [VariableAccess] x
|
||||
# 60| Type = [IntType] int
|
||||
# 60| ValueCategory = prvalue(load)
|
||||
# 61| getStmt(2): [DeclStmt] declaration
|
||||
# 61| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
|
||||
# 61| Type = [IntType] int
|
||||
# 61| getVariable().getInitializer(): [Initializer] initializer for y
|
||||
# 61| getExpr(): [PointerDereferenceExpr] * ...
|
||||
# 61| Type = [IntType] int
|
||||
# 61| ValueCategory = prvalue(load)
|
||||
# 61| getOperand(): [VariableAccess] d
|
||||
# 61| Type = [IntPointerType] int *
|
||||
# 61| ValueCategory = prvalue(load)
|
||||
# 63| getCondition(): [Literal] 1
|
||||
# 63| Type = [IntType] int
|
||||
# 63| Value = [Literal] 1
|
||||
# 63| ValueCategory = prvalue
|
||||
# 63| getExcept(): [BlockStmt] { ... }
|
||||
# 64| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 64| getExpr(): [FunctionCall] call to sink
|
||||
# 64| Type = [VoidType] void
|
||||
# 64| ValueCategory = prvalue
|
||||
# 64| getArgument(0): [VariableAccess] x
|
||||
# 64| Type = [IntType] int
|
||||
# 64| ValueCategory = prvalue(load)
|
||||
# 66| getStmt(2): [ReturnStmt] return ...
|
||||
try_except.cpp:
|
||||
# 3| [TopLevelFunction] void ProbeFunction()
|
||||
# 3| <params>:
|
||||
|
||||
@@ -39258,6 +39258,105 @@ try_except.c:
|
||||
# 46| Block 7
|
||||
# 46| v46_10(void) = Unreached :
|
||||
|
||||
# 56| void k(int*, int*, int*)
|
||||
# 56| Block 0
|
||||
# 56| v56_1(void) = EnterFunction :
|
||||
# 56| m56_2(unknown) = AliasedDefinition :
|
||||
# 56| m56_3(unknown) = InitializeNonLocal :
|
||||
# 56| m56_4(unknown) = Chi : total:m56_2, partial:m56_3
|
||||
# 56| r56_5(glval<int *>) = VariableAddress[b] :
|
||||
# 56| m56_6(int *) = InitializeParameter[b] : &:r56_5
|
||||
# 56| r56_7(int *) = Load[b] : &:r56_5, m56_6
|
||||
# 56| m56_8(unknown) = InitializeIndirection[b] : &:r56_7
|
||||
# 56| r56_9(glval<int *>) = VariableAddress[c] :
|
||||
# 56| m56_10(int *) = InitializeParameter[c] : &:r56_9
|
||||
# 56| r56_11(int *) = Load[c] : &:r56_9, m56_10
|
||||
# 56| m56_12(unknown) = InitializeIndirection[c] : &:r56_11
|
||||
# 56| r56_13(glval<int *>) = VariableAddress[d] :
|
||||
# 56| m56_14(int *) = InitializeParameter[d] : &:r56_13
|
||||
# 56| r56_15(int *) = Load[d] : &:r56_13, m56_14
|
||||
# 56| m56_16(unknown) = InitializeIndirection[d] : &:r56_15
|
||||
# 57| r57_1(glval<int>) = VariableAddress[x] :
|
||||
# 57| r57_2(int) = Constant[0] :
|
||||
# 57| m57_3(int) = Store[x] : &:r57_1, r57_2
|
||||
# 59| r59_1(glval<int *>) = VariableAddress[b] :
|
||||
# 59| r59_2(int *) = Load[b] : &:r59_1, m56_6
|
||||
# 59| r59_3(int) = Load[?] : &:r59_2, ~m56_8
|
||||
#-----| Goto -> Block 1
|
||||
#-----| SEH Exception -> Block 6
|
||||
|
||||
# 59| Block 1
|
||||
# 59| r59_4(glval<int>) = VariableAddress[x] :
|
||||
# 59| m59_5(int) = Store[x] : &:r59_4, r59_3
|
||||
# 60| r60_1(glval<int>) = VariableAddress[x] :
|
||||
# 60| r60_2(int) = Load[x] : &:r60_1, m59_5
|
||||
# 60| r60_3(glval<int *>) = VariableAddress[c] :
|
||||
# 60| r60_4(int *) = Load[c] : &:r60_3, m56_10
|
||||
# 60| r60_5(glval<int>) = CopyValue : r60_4
|
||||
# 60| m60_6(int) = Store[?] : &:r60_5, r60_2
|
||||
# 60| m60_7(unknown) = Chi : total:m56_12, partial:m60_6
|
||||
#-----| Goto -> Block 2
|
||||
#-----| SEH Exception -> Block 6
|
||||
|
||||
# 61| Block 2
|
||||
# 61| r61_1(glval<int>) = VariableAddress[y] :
|
||||
# 61| r61_2(glval<int *>) = VariableAddress[d] :
|
||||
# 61| r61_3(int *) = Load[d] : &:r61_2, m56_14
|
||||
# 61| r61_4(int) = Load[?] : &:r61_3, ~m56_16
|
||||
#-----| Goto -> Block 3
|
||||
#-----| SEH Exception -> Block 6
|
||||
|
||||
# 61| Block 3
|
||||
# 61| m61_5(int) = Store[y] : &:r61_1, r61_4
|
||||
#-----| Goto -> Block 8
|
||||
|
||||
# 63| Block 4
|
||||
# 63| r63_1(int) = Constant[0] :
|
||||
# 63| r63_2(bool) = CompareEQ : r63_9, r63_1
|
||||
# 63| v63_3(void) = ConditionalBranch : r63_2
|
||||
#-----| False -> Block 5
|
||||
#-----| True -> Block 9
|
||||
|
||||
# 63| Block 5
|
||||
# 63| r63_4(int) = Constant[1] :
|
||||
# 63| r63_5(bool) = CompareEQ : r63_9, r63_4
|
||||
# 63| v63_6(void) = ConditionalBranch : r63_5
|
||||
#-----| False -> Block 9
|
||||
#-----| True -> Block 7
|
||||
|
||||
# 63| Block 6
|
||||
# 63| m63_7(unknown) = Phi : from 0:m56_12, from 1:m60_7, from 2:m60_7
|
||||
# 63| m63_8(int) = Phi : from 0:m57_3, from 1:m59_5, from 2:m59_5
|
||||
# 63| r63_9(int) = Constant[1] :
|
||||
# 63| r63_10(int) = Constant[-1] :
|
||||
# 63| r63_11(bool) = CompareEQ : r63_9, r63_10
|
||||
# 63| v63_12(void) = ConditionalBranch : r63_11
|
||||
#-----| False -> Block 4
|
||||
#-----| True -> Block 9
|
||||
|
||||
# 64| Block 7
|
||||
# 64| r64_1(glval<unknown>) = FunctionAddress[sink] :
|
||||
# 64| r64_2(glval<int>) = VariableAddress[x] :
|
||||
# 64| r64_3(int) = Load[x] : &:r64_2, m63_8
|
||||
# 64| v64_4(void) = Call[sink] : func:r64_1, 0:r64_3
|
||||
# 64| m64_5(unknown) = ^CallSideEffect : ~m56_4
|
||||
# 64| m64_6(unknown) = Chi : total:m56_4, partial:m64_5
|
||||
#-----| Goto -> Block 8
|
||||
|
||||
# 66| Block 8
|
||||
# 66| m66_1(unknown) = Phi : from 3:m60_7, from 7:m63_7
|
||||
# 66| m66_2(unknown) = Phi : from 3:~m56_4, from 7:~m64_6
|
||||
# 66| v66_3(void) = NoOp :
|
||||
# 56| v56_17(void) = ReturnIndirection[b] : &:r56_7, m56_8
|
||||
# 56| v56_18(void) = ReturnIndirection[c] : &:r56_11, m66_1
|
||||
# 56| v56_19(void) = ReturnIndirection[d] : &:r56_15, m56_16
|
||||
# 56| v56_20(void) = ReturnVoid :
|
||||
# 56| v56_21(void) = AliasedUse : ~m66_2
|
||||
# 56| v56_22(void) = ExitFunction :
|
||||
|
||||
# 56| Block 9
|
||||
# 56| v56_23(void) = Unreached :
|
||||
|
||||
try_except.cpp:
|
||||
# 6| void f_cpp()
|
||||
# 6| Block 0
|
||||
|
||||
@@ -37533,6 +37533,101 @@ try_except.c:
|
||||
# 46| v46_9(void) = ReturnVoid :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 56| void k(int*, int*, int*)
|
||||
# 56| Block 0
|
||||
# 56| v56_1(void) = EnterFunction :
|
||||
# 56| mu56_2(unknown) = AliasedDefinition :
|
||||
# 56| mu56_3(unknown) = InitializeNonLocal :
|
||||
# 56| r56_4(glval<int *>) = VariableAddress[b] :
|
||||
# 56| mu56_5(int *) = InitializeParameter[b] : &:r56_4
|
||||
# 56| r56_6(int *) = Load[b] : &:r56_4, ~m?
|
||||
# 56| mu56_7(unknown) = InitializeIndirection[b] : &:r56_6
|
||||
# 56| r56_8(glval<int *>) = VariableAddress[c] :
|
||||
# 56| mu56_9(int *) = InitializeParameter[c] : &:r56_8
|
||||
# 56| r56_10(int *) = Load[c] : &:r56_8, ~m?
|
||||
# 56| mu56_11(unknown) = InitializeIndirection[c] : &:r56_10
|
||||
# 56| r56_12(glval<int *>) = VariableAddress[d] :
|
||||
# 56| mu56_13(int *) = InitializeParameter[d] : &:r56_12
|
||||
# 56| r56_14(int *) = Load[d] : &:r56_12, ~m?
|
||||
# 56| mu56_15(unknown) = InitializeIndirection[d] : &:r56_14
|
||||
# 57| r57_1(glval<int>) = VariableAddress[x] :
|
||||
# 57| r57_2(int) = Constant[0] :
|
||||
# 57| mu57_3(int) = Store[x] : &:r57_1, r57_2
|
||||
# 59| r59_1(glval<int *>) = VariableAddress[b] :
|
||||
# 59| r59_2(int *) = Load[b] : &:r59_1, ~m?
|
||||
# 59| r59_3(int) = Load[?] : &:r59_2, ~m?
|
||||
#-----| Goto -> Block 3
|
||||
#-----| SEH Exception -> Block 8
|
||||
|
||||
# 56| Block 1
|
||||
# 56| v56_16(void) = AliasedUse : ~m?
|
||||
# 56| v56_17(void) = ExitFunction :
|
||||
|
||||
# 56| Block 2
|
||||
# 56| v56_18(void) = Unwind :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 59| Block 3
|
||||
# 59| r59_4(glval<int>) = VariableAddress[x] :
|
||||
# 59| mu59_5(int) = Store[x] : &:r59_4, r59_3
|
||||
# 60| r60_1(glval<int>) = VariableAddress[x] :
|
||||
# 60| r60_2(int) = Load[x] : &:r60_1, ~m?
|
||||
# 60| r60_3(glval<int *>) = VariableAddress[c] :
|
||||
# 60| r60_4(int *) = Load[c] : &:r60_3, ~m?
|
||||
# 60| r60_5(glval<int>) = CopyValue : r60_4
|
||||
# 60| mu60_6(int) = Store[?] : &:r60_5, r60_2
|
||||
#-----| Goto -> Block 4
|
||||
#-----| SEH Exception -> Block 8
|
||||
|
||||
# 61| Block 4
|
||||
# 61| r61_1(glval<int>) = VariableAddress[y] :
|
||||
# 61| r61_2(glval<int *>) = VariableAddress[d] :
|
||||
# 61| r61_3(int *) = Load[d] : &:r61_2, ~m?
|
||||
# 61| r61_4(int) = Load[?] : &:r61_3, ~m?
|
||||
#-----| Goto -> Block 5
|
||||
#-----| SEH Exception -> Block 8
|
||||
|
||||
# 61| Block 5
|
||||
# 61| mu61_5(int) = Store[y] : &:r61_1, r61_4
|
||||
#-----| Goto -> Block 10
|
||||
|
||||
# 63| Block 6
|
||||
# 63| r63_1(int) = Constant[0] :
|
||||
# 63| r63_2(bool) = CompareEQ : r63_7, r63_1
|
||||
# 63| v63_3(void) = ConditionalBranch : r63_2
|
||||
#-----| False -> Block 7
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 63| Block 7
|
||||
# 63| r63_4(int) = Constant[1] :
|
||||
# 63| r63_5(bool) = CompareEQ : r63_7, r63_4
|
||||
# 63| v63_6(void) = ConditionalBranch : r63_5
|
||||
#-----| True -> Block 9
|
||||
|
||||
# 63| Block 8
|
||||
# 63| r63_7(int) = Constant[1] :
|
||||
# 63| r63_8(int) = Constant[-1] :
|
||||
# 63| r63_9(bool) = CompareEQ : r63_7, r63_8
|
||||
# 63| v63_10(void) = ConditionalBranch : r63_9
|
||||
#-----| False -> Block 6
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 64| Block 9
|
||||
# 64| r64_1(glval<unknown>) = FunctionAddress[sink] :
|
||||
# 64| r64_2(glval<int>) = VariableAddress[x] :
|
||||
# 64| r64_3(int) = Load[x] : &:r64_2, ~m?
|
||||
# 64| v64_4(void) = Call[sink] : func:r64_1, 0:r64_3
|
||||
# 64| mu64_5(unknown) = ^CallSideEffect : ~m?
|
||||
#-----| Goto -> Block 10
|
||||
|
||||
# 66| Block 10
|
||||
# 66| v66_1(void) = NoOp :
|
||||
# 56| v56_19(void) = ReturnIndirection[b] : &:r56_6, ~m?
|
||||
# 56| v56_20(void) = ReturnIndirection[c] : &:r56_10, ~m?
|
||||
# 56| v56_21(void) = ReturnIndirection[d] : &:r56_14, ~m?
|
||||
# 56| v56_22(void) = ReturnVoid :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
try_except.cpp:
|
||||
# 6| void f_cpp()
|
||||
# 6| Block 0
|
||||
|
||||
@@ -52,3 +52,15 @@ void j(int b) {
|
||||
sink(x);
|
||||
}
|
||||
}
|
||||
|
||||
void k(int *b, int *c, int *d) {
|
||||
int x = 0;
|
||||
__try {
|
||||
x = *b;
|
||||
*c = x;
|
||||
int y = *d;
|
||||
}
|
||||
__except (1) {
|
||||
sink(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,6 @@ void throw_cpp(int b) {
|
||||
}
|
||||
}
|
||||
__except (1) {
|
||||
sink(x);
|
||||
sink(x);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user