mirror of
https://github.com/github/codeql.git
synced 2026-04-27 09:45:15 +02:00
Merge branch 'main' into pawel_signatures_conversion
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a predicate `getAnAttribute` to `Namespace` to retrieve a namespace attribute.
|
||||
@@ -42,6 +42,8 @@ module PrivateCleartextWrite {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module WriteFlow = TaintTracking::Global<WriteConfig>;
|
||||
|
||||
@@ -99,6 +99,11 @@ class Namespace extends NameQualifyingElement, @namespace {
|
||||
|
||||
/** Gets a file which declares (part of) this namespace. */
|
||||
File getAFile() { result = this.getADeclarationEntry().getLocation().getFile() }
|
||||
|
||||
/** Gets an attribute of this namespace. */
|
||||
Attribute getAnAttribute() {
|
||||
namespaceattributes(underlyingElement(this), unresolveElement(result))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@ private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
||||
private import semmle.code.cpp.ir.internal.CppType
|
||||
private import semmle.code.cpp.models.interfaces.SideEffect
|
||||
private import semmle.code.cpp.models.interfaces.Throwing
|
||||
private import semmle.code.cpp.models.interfaces.NonThrowing
|
||||
private import InstructionTag
|
||||
private import SideEffects
|
||||
private import TranslatedElement
|
||||
@@ -366,6 +367,10 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
|
||||
or
|
||||
exists(MicrosoftTryStmt tryStmt | tryStmt.getStmt() = expr.getEnclosingStmt().getParent*()) and
|
||||
e instanceof SehExceptionEdge
|
||||
or
|
||||
not expr.getTarget() instanceof NonCppThrowingFunction and
|
||||
exists(TryStmt tryStmt | tryStmt.getStmt() = expr.getEnclosingStmt().getParent*()) and
|
||||
e instanceof CppExceptionEdge
|
||||
}
|
||||
|
||||
final override predicate mustThrowException(ExceptionEdge e) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1139,6 +1139,11 @@ varattributes(
|
||||
int spec_id: @attribute ref
|
||||
);
|
||||
|
||||
namespaceattributes(
|
||||
int namespace_id: @namespace ref,
|
||||
int spec_id: @attribute ref
|
||||
);
|
||||
|
||||
stmtattributes(
|
||||
int stmt_id: @stmt ref,
|
||||
int spec_id: @attribute ref
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add a predicate `getAnAttribute` to `Namespace`
|
||||
compatibility: backwards
|
||||
@@ -48,6 +48,8 @@ module CastToPointerArithFlowConfig implements DataFlow::StateConfigSig {
|
||||
predicate isBarrierIn(DataFlow::Node node) { isSource(node, _) }
|
||||
|
||||
predicate isBarrierOut(DataFlow::Node node) { isSink(node, _) }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -141,6 +141,8 @@ private module NetworkToBufferSizeConfig implements DataFlow::ConfigSig {
|
||||
gc.controls(node.asExpr().getBasicBlock(), _)
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module NetworkToBufferSizeFlow = DataFlow::Global<NetworkToBufferSizeConfig>;
|
||||
|
||||
@@ -39,6 +39,8 @@ module Config implements DataFlow::ConfigSig {
|
||||
or
|
||||
node.asCertainDefinition().getUnspecifiedType() instanceof ArithmeticType
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
@@ -66,6 +66,8 @@ module ImproperArrayIndexValidationConfig implements DataFlow::ConfigSig {
|
||||
not offsetIsAlwaysInBounds(arrayExpr, offsetExpr)
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module ImproperArrayIndexValidation = TaintTracking::Global<ImproperArrayIndexValidationConfig>;
|
||||
|
||||
@@ -44,6 +44,8 @@ module Config implements DataFlow::ConfigSig {
|
||||
or
|
||||
isArithmeticNonCharType(node.asCertainDefinition().getUnspecifiedType())
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
@@ -94,6 +94,8 @@ module Config implements DataFlow::ConfigSig {
|
||||
not iTo instanceof PointerArithmeticInstruction
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
@@ -34,6 +34,8 @@ module ExposedSystemDataConfig implements DataFlow::ConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node.asIndirectArgument() = any(MemsetFunction func).getACallToThisFunction().getAnArgument()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module ExposedSystemData = TaintTracking::Global<ExposedSystemDataConfig>;
|
||||
|
||||
@@ -54,6 +54,8 @@ module PotentiallyExposedSystemDataConfig implements DataFlow::ConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node.asIndirectArgument() = any(MemsetFunction func).getACallToThisFunction().getAnArgument()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module PotentiallyExposedSystemData = TaintTracking::Global<PotentiallyExposedSystemDataConfig>;
|
||||
|
||||
@@ -45,6 +45,8 @@ module XxeConfig implements DataFlow::StateConfigSig {
|
||||
}
|
||||
|
||||
predicate neverSkip(DataFlow::Node node) { none() }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module XxeFlow = DataFlow::GlobalWithState<XxeConfig>;
|
||||
|
||||
@@ -48,6 +48,8 @@ module WordexpTaintConfig implements DataFlow::ConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node.asExpr().getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module WordexpTaint = TaintTracking::Global<WordexpTaintConfig>;
|
||||
|
||||
@@ -30,6 +30,8 @@ module MultToAllocConfig implements DataFlow::ConfigSig {
|
||||
// something that affects an allocation size
|
||||
node.asExpr() = any(HeuristicAllocationExpr ae).getSizeExpr().getAChild*()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module MultToAlloc = DataFlow::Global<MultToAllocConfig>;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
| file://:0:0:0:0 | MultiSquared | test.cpp:10:13:10:22 | deprecated |
|
||||
| file://:0:0:0:0 | MultiSquared | test.cpp:10:25:10:36 | maybe_unused |
|
||||
| file://:0:0:0:0 | MultiSquared | test.cpp:11:13:11:22 | deprecated |
|
||||
| file://:0:0:0:0 | MultiSquared | test.cpp:11:25:11:36 | maybe_unused |
|
||||
| file://:0:0:0:0 | NamespaceTest | test.cpp:1:26:1:35 | deprecated |
|
||||
| file://:0:0:0:0 | NamespaceTest | test.cpp:2:26:2:35 | deprecated |
|
||||
| file://:0:0:0:0 | NamespaceTest | test.cpp:3:26:3:37 | maybe_unused |
|
||||
| test.cpp:4:53:4:61 | MultiAttr | test.cpp:4:26:4:35 | deprecated |
|
||||
| test.cpp:4:53:4:61 | MultiAttr | test.cpp:4:38:4:49 | maybe_unused |
|
||||
| test.cpp:6:43:6:56 | OuterNamespace::InnerNamespace | test.cpp:6:30:6:39 | deprecated |
|
||||
| test.cpp:9:46:9:61 | NamespaceSquared | test.cpp:9:13:9:22 | deprecated |
|
||||
@@ -0,0 +1,4 @@
|
||||
import cpp
|
||||
|
||||
from Namespace ns
|
||||
select ns, ns.getAnAttribute()
|
||||
11
cpp/ql/test/library-tests/attributes/namespace/test.cpp
Normal file
11
cpp/ql/test/library-tests/attributes/namespace/test.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace __attribute__((deprecated)) NamespaceTest {}
|
||||
namespace __attribute__((deprecated)) NamespaceTest {}
|
||||
namespace __attribute__((maybe_unused)) NamespaceTest {}
|
||||
namespace __attribute__((deprecated, maybe_unused)) MultiAttr {}
|
||||
namespace OuterNamespace {
|
||||
namespace __attribute__((deprecated)) InnerNamespace {}
|
||||
}
|
||||
|
||||
namespace [[deprecated("NamespaceSquared")]] NamespaceSquared {}
|
||||
namespace [[deprecated, maybe_unused]] MultiSquared {}
|
||||
namespace [[deprecated, maybe_unused]] MultiSquared {}
|
||||
@@ -448,7 +448,6 @@ astGuardsControl
|
||||
| test.cpp:31:7:31:13 | ... == ... | false | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | 31 | 32 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | false | 53 | 53 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | true | 43 | 45 |
|
||||
astGuardsEnsure
|
||||
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | test.c:7:13:7:13 | 0 | 1 | 10 | 11 |
|
||||
@@ -893,8 +892,6 @@ astGuardsEnsure_const
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 31 | 32 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | 43 | 45 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 1 | 53 | 53 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 0 | 53 | 53 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 1 | 43 | 45 |
|
||||
irGuards
|
||||
| test.c:7:9:7:13 | CompareGT: ... > ... |
|
||||
@@ -1301,8 +1298,8 @@ irGuardsControl
|
||||
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | false | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | true | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | true | 32 | 32 |
|
||||
| test.cpp:42:13:42:20 | Call: call to getABool | false | 53 | 53 |
|
||||
| test.cpp:42:13:42:20 | Call: call to getABool | true | 44 | 44 |
|
||||
| test.cpp:42:13:42:20 | Call: call to getABool | true | 45 | 45 |
|
||||
irGuardsEnsure
|
||||
| test.c:7:9:7:13 | CompareGT: ... > ... | test.c:7:9:7:9 | Load: x | < | test.c:7:13:7:13 | Constant: 0 | 1 | 11 | 11 |
|
||||
| test.c:7:9:7:13 | CompareGT: ... > ... | test.c:7:9:7:9 | Load: x | >= | test.c:7:13:7:13 | Constant: 0 | 1 | 8 | 8 |
|
||||
@@ -1781,6 +1778,6 @@ irGuardsEnsure_const
|
||||
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:13 | CompareEQ: ... == ... | == | 1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:13 | CompareEQ: ... == ... | == | 1 | 32 | 32 |
|
||||
| test.cpp:42:13:42:20 | Call: call to getABool | test.cpp:42:13:42:20 | Call: call to getABool | != | 0 | 44 | 44 |
|
||||
| test.cpp:42:13:42:20 | Call: call to getABool | test.cpp:42:13:42:20 | Call: call to getABool | != | 1 | 53 | 53 |
|
||||
| test.cpp:42:13:42:20 | Call: call to getABool | test.cpp:42:13:42:20 | Call: call to getABool | == | 0 | 53 | 53 |
|
||||
| test.cpp:42:13:42:20 | Call: call to getABool | test.cpp:42:13:42:20 | Call: call to getABool | != | 0 | 45 | 45 |
|
||||
| test.cpp:42:13:42:20 | Call: call to getABool | test.cpp:42:13:42:20 | Call: call to getABool | == | 1 | 44 | 44 |
|
||||
| test.cpp:42:13:42:20 | Call: call to getABool | test.cpp:42:13:42:20 | Call: call to getABool | == | 1 | 45 | 45 |
|
||||
|
||||
@@ -104,7 +104,6 @@
|
||||
| test.cpp:31:7:31:13 | ... == ... | false | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | 31 | 32 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | false | 53 | 53 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | true | 43 | 45 |
|
||||
| test.cpp:61:10:61:10 | i | Case[0] | 62 | 64 |
|
||||
| test.cpp:61:10:61:10 | i | Case[1] | 65 | 66 |
|
||||
|
||||
@@ -635,8 +635,6 @@ unary
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 31 | 32 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | 43 | 45 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 1 | 53 | 53 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 0 | 53 | 53 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 1 | 43 | 45 |
|
||||
| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 0 | 62 | 64 |
|
||||
| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 1 | 65 | 66 |
|
||||
|
||||
@@ -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>:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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