Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
68 changes: 68 additions & 0 deletions cpp/ql/test/library-tests/ir/ir/PrintAST.expected
Original file line number Diff line number Diff line change
Expand Up @@ -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>:
Expand Down
99 changes: 99 additions & 0 deletions cpp/ql/test/library-tests/ir/ir/aliased_ir.expected
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
95 changes: 95 additions & 0 deletions cpp/ql/test/library-tests/ir/ir/raw_ir.expected
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions cpp/ql/test/library-tests/ir/ir/try_except.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
2 changes: 1 addition & 1 deletion cpp/ql/test/library-tests/ir/ir/try_except.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ void throw_cpp(int b) {
}
}
__except (1) {
sink(x);
sink(x);
}
}
Loading