Merge pull request #19734 from github/idrissrio/goto

C++: Add  support to `__leave`
This commit is contained in:
Idriss Riouak
2025-06-13 16:20:26 +02:00
committed by GitHub
14 changed files with 10837 additions and 770 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
class Stmt extends @stmt {
string toString() { none() }
}
class Location extends @location_stmt {
string toString() { none() }
}
from Stmt id, int kind, Location loc, int new_kind
where
stmts(id, kind, loc) and
if kind = 40 then new_kind = 4 else new_kind = kind
select id, new_kind, loc

View File

@@ -0,0 +1,3 @@
description: Support `__leave` statement
compatibility: full
stmts.rel: run stmts.qlo

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* The Microsoft-specific `__leave` statement is now supported.
* A new class `LeaveStmt` extending `JumpStmt` was added to represent `__leave` statements.

View File

@@ -841,6 +841,41 @@ private Stmt getEnclosingBreakable(Stmt s) {
else result = getEnclosingBreakable(s.getParent().getEnclosingStmt())
}
/**
* A Microsoft C/C++ `__leave` statement.
*
* For example, the `__leave` statement in the following code:
* ```
* __try {
* if (err) __leave;
* ...
* }
* __finally {
*
* }
* ```
*/
class LeaveStmt extends JumpStmt, @stmt_leave {
override string getAPrimaryQlClass() { result = "LeaveStmt" }
override string toString() { result = "__leave;" }
override predicate mayBeImpure() { none() }
override predicate mayBeGloballyImpure() { none() }
/**
* Gets the `__try` statement that this `__leave` exits.
*/
MicrosoftTryStmt getEnclosingTry() { result = getEnclosingTry(this) }
}
private MicrosoftTryStmt getEnclosingTry(Stmt s) {
if s.getParent().getEnclosingStmt() instanceof MicrosoftTryStmt
then result = s.getParent().getEnclosingStmt()
else result = getEnclosingTry(s.getParent().getEnclosingStmt())
}
/**
* A C/C++ 'label' statement.
*

View File

@@ -2213,6 +2213,7 @@ case @stmt.kind of
| 37 = @stmt_co_return
| 38 = @stmt_consteval_if
| 39 = @stmt_not_consteval_if
| 40 = @stmt_leave
;
type_vla(
@@ -2349,7 +2350,7 @@ blockscope(
int enclosing: @parameterized_element ref
);
@jump = @stmt_goto | @stmt_break | @stmt_continue;
@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
@jumporlabel = @jump | @stmt_label | @literal;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Support `__leave` statement
compatibility: partial

View File

@@ -0,0 +1,28 @@
//semmle-extractor-options: --microsoft
void leave_try_finally_test(bool condition){
__try {
if(condition){
__leave;
}
}
__finally {
}
}
int except_handler();
void leave_try_except_test(bool condition){
__try {
try {
if(condition)
__leave;
}
catch(...) {
}
if(condition){
__leave;
}
}
__except (except_handler()) {
}
}

View File

@@ -0,0 +1,3 @@
| leave.cpp:5:8:5:15 | __leave; | leave.cpp:3:5:7:5 | __try { ... } __finally { ... } |
| leave.cpp:18:17:18:24 | __leave; | leave.cpp:15:5:25:5 | __try { ... } __except( ... ) { ... } |
| leave.cpp:23:13:23:20 | __leave; | leave.cpp:15:5:25:5 | __try { ... } __except( ... ) { ... } |

View File

@@ -0,0 +1,4 @@
import cpp
from LeaveStmt s
select s, s.getEnclosingTry()