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
4 changes: 4 additions & 0 deletions unified/extractor/ast_types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ supertypes:
- for_each_stmt
- while_stmt
- do_while_stmt
- defer_stmt

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure we can do the accurate CFG later.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added this to the language feature backlog

- labeled_stmt
callable:
- top_level
Expand Down Expand Up @@ -346,6 +347,9 @@ named:
body?: block
condition: expr

defer_stmt:
body: expr

# `do { body } catch pattern { ... } catch ...`. Swift uses `do`/`catch`
# for error handling; for languages with `try`/`catch`, this is the same shape.
try_expr:
Expand Down
3 changes: 2 additions & 1 deletion unified/extractor/src/languages/swift/swift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,8 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
=>
(do_while_stmt condition: {cond} body: {body})
),
// A `defer` statement
rule!((deferStmt body: @body) => (defer_stmt body: {body})),
// A labeled statement (`outer: for … { }`). swift-syntax stores the
// label and colon as separate tokens, so the label token is already the
// bare name (no trailing `:` to strip).
Expand Down Expand Up @@ -1387,7 +1389,6 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
rule!((compositionType) => (unsupported_node)),
rule!((consumeExpr) => (unsupported_node)),
rule!((copyExpr) => (unsupported_node)),
rule!((deferStmt) => (unsupported_node)),
rule!((discardStmt) => (unsupported_node)),
rule!((fallThroughStmt) => (unsupported_node)),
rule!((ifConfigDecl) => (unsupported_node)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,15 @@ top_level source="⟨body⟩"
body:
block source="{\n ⟨stmt⟩\n ⟨stmt⟩\n}"
stmt:
unsupported_node "defer { print(\"cleanup\") }" source="defer { print(\"cleanup\") }"
defer_stmt source="defer ⟨body⟩"
body:
block source="{ ⟨stmt⟩ }"
stmt:
call_expr source="⟨callee⟩(⟨argument⟩)"
callee: identifier "print" source="print"
argument:
argument source="⟨value⟩"
value: string_literal "\"cleanup\"" source="\"cleanup\""
call_expr source="⟨callee⟩(⟨argument⟩)"
callee: identifier "print" source="print"
argument:
Expand Down
16 changes: 16 additions & 0 deletions unified/ql/lib/codeql/unified/internal/Ast.qll
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,18 @@ module Unified {
}
}

/** A class representing `defer_stmt` nodes. */
class DeferStmt extends @unified_defer_stmt, F::Stmt {
/** Gets the name of the primary QL class for this element. */
final override string getAPrimaryQlClass() { result = "DeferStmt" }

/** Gets the node corresponding to the field `body`. */
final F::Expr getBody() { unified_defer_stmt_def(this, result) }

/** Gets a field or child node of this node. */
final override F::AstNode getAFieldOrChild() { unified_defer_stmt_def(this, result) }
}

/** A class representing `destructor_declaration` nodes. */
class DestructorDeclaration extends @unified_destructor_declaration, F::Callable, F::Member,
F::Stmt
Expand Down Expand Up @@ -1619,6 +1631,8 @@ module Unified {
or
result = node.(ContinueExpr).getLabelNameNode() and i = -1 and name = "getLabelNameNode"
or
result = node.(DeferStmt).getBody() and i = -1 and name = "getBody"
or
result = node.(DestructorDeclaration).getBody() and i = -1 and name = "getBody"
or
result = node.(DestructorDeclaration).getModifier(i) and name = "getModifier"
Expand Down Expand Up @@ -1874,6 +1888,8 @@ module UnifiedFinal {

final class ContinueExpr = F::ContinueExpr;

final class DeferStmt = F::DeferStmt;

final class DestructorDeclaration = F::DestructorDeclaration;

final class DoWhileStmt = F::DoWhileStmt;
Expand Down
9 changes: 7 additions & 2 deletions unified/ql/lib/unified.dbscheme
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,11 @@ unified_continue_expr_def(
unique int id: @unified_continue_expr
);

unified_defer_stmt_def(
unique int id: @unified_defer_stmt,
int body: @unified_expr ref
);

#keyset[unified_destructor_declaration, index]
unified_destructor_declaration_modifier(
int unified_destructor_declaration: @unified_destructor_declaration ref,
Expand Down Expand Up @@ -746,7 +751,7 @@ unified_return_expr_def(
unique int id: @unified_return_expr
);

@unified_stmt = @unified_accessor_declaration | @unified_class_like_declaration | @unified_constructor_declaration | @unified_destructor_declaration | @unified_do_while_stmt | @unified_expr | @unified_for_each_stmt | @unified_function_declaration | @unified_guard_if_stmt | @unified_import_declaration | @unified_labeled_stmt | @unified_operator_syntax_declaration | @unified_type_alias_declaration | @unified_variable_declaration | @unified_while_stmt
@unified_stmt = @unified_accessor_declaration | @unified_class_like_declaration | @unified_constructor_declaration | @unified_defer_stmt | @unified_destructor_declaration | @unified_do_while_stmt | @unified_expr | @unified_for_each_stmt | @unified_function_declaration | @unified_guard_if_stmt | @unified_import_declaration | @unified_labeled_stmt | @unified_operator_syntax_declaration | @unified_type_alias_declaration | @unified_variable_declaration | @unified_while_stmt

#keyset[unified_string_interpolation_expr, index]
unified_string_interpolation_expr_element(
Expand Down Expand Up @@ -1001,7 +1006,7 @@ unified_trivia_tokeninfo(
string value: string ref
);

@unified_ast_node = @unified_accessor_declaration | @unified_argument | @unified_array_literal | @unified_associated_type_declaration | @unified_base_type | @unified_binary_expr | @unified_block | @unified_bound_type_constraint | @unified_break_expr | @unified_bulk_importing_pattern | @unified_call_expr | @unified_catch_clause | @unified_class_like_declaration | @unified_conditional_pattern | @unified_constructor_declaration | @unified_continue_expr | @unified_destructor_declaration | @unified_do_while_stmt | @unified_equality_type_constraint | @unified_expr_pattern | @unified_for_each_stmt | @unified_function_declaration | @unified_function_expr | @unified_generic_type_expr | @unified_guard_if_stmt | @unified_if_expr | @unified_import_declaration | @unified_initializer_declaration | @unified_key_value_pair | @unified_labeled_stmt | @unified_map_literal | @unified_member_access_expr | @unified_named_pattern | @unified_operator_syntax_declaration | @unified_or_pattern | @unified_parameter | @unified_pattern_guard_expr | @unified_return_expr | @unified_string_interpolation_expr | @unified_switch_case | @unified_switch_expr | @unified_throw_expr | @unified_token | @unified_top_level | @unified_trivia_token | @unified_try_expr | @unified_tuple_expr | @unified_type_alias_declaration | @unified_type_cast_expr | @unified_type_parameter | @unified_type_test_expr | @unified_unary_expr | @unified_unresolved_operator_sequence | @unified_variable_declaration | @unified_while_stmt
@unified_ast_node = @unified_accessor_declaration | @unified_argument | @unified_array_literal | @unified_associated_type_declaration | @unified_base_type | @unified_binary_expr | @unified_block | @unified_bound_type_constraint | @unified_break_expr | @unified_bulk_importing_pattern | @unified_call_expr | @unified_catch_clause | @unified_class_like_declaration | @unified_conditional_pattern | @unified_constructor_declaration | @unified_continue_expr | @unified_defer_stmt | @unified_destructor_declaration | @unified_do_while_stmt | @unified_equality_type_constraint | @unified_expr_pattern | @unified_for_each_stmt | @unified_function_declaration | @unified_function_expr | @unified_generic_type_expr | @unified_guard_if_stmt | @unified_if_expr | @unified_import_declaration | @unified_initializer_declaration | @unified_key_value_pair | @unified_labeled_stmt | @unified_map_literal | @unified_member_access_expr | @unified_named_pattern | @unified_operator_syntax_declaration | @unified_or_pattern | @unified_parameter | @unified_pattern_guard_expr | @unified_return_expr | @unified_string_interpolation_expr | @unified_switch_case | @unified_switch_expr | @unified_throw_expr | @unified_token | @unified_top_level | @unified_trivia_token | @unified_try_expr | @unified_tuple_expr | @unified_type_alias_declaration | @unified_type_cast_expr | @unified_type_parameter | @unified_type_test_expr | @unified_unary_expr | @unified_unresolved_operator_sequence | @unified_variable_declaration | @unified_while_stmt

unified_ast_node_location(
unique int node: @unified_ast_node ref,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,14 @@
| 152 | cfg.swift:152:7:152:18 | Block | 'Block -V false -^ ReturnExpr' |
| 168 | cfg.swift:168:1:184:1 | func testDefer | 'func testDefer' |
| 168 | cfg.swift:168:16:168:16 | x | 'x -> Block' |
| 170 | cfg.swift:170:3:172:3 | | '' |
| 174 | cfg.swift:174:3:176:3 | | '' |
| 178 | cfg.swift:178:3:183:3 | | '' |
| 170 | cfg.swift:170:3:172:3 | DeferStmt | 'DeferStmt -V Block' |
| 171 | cfg.swift:171:5:171:9 | print | 'print -> Argument -V "4" -^ print(...)' |
| 174 | cfg.swift:174:3:176:3 | DeferStmt | 'DeferStmt -V Block' |
| 175 | cfg.swift:175:5:175:9 | print | 'print -> Argument -V "3" -^ print(...)' |
| 178 | cfg.swift:178:3:183:3 | DeferStmt | 'DeferStmt -V Block' |
| 179 | cfg.swift:179:5:179:9 | print | 'print -> Argument -V "1" -^ print(...)' |
| 180 | cfg.swift:180:6:182:5 | DeferStmt | 'DeferStmt -V Block' |
| 181 | cfg.swift:181:7:181:11 | print | 'print -> Argument -V "2" -^ print(...)' |
| 186 | cfg.swift:186:1:198:1 | func m1 | 'func m1' |
| 186 | cfg.swift:186:9:186:9 | x | 'x -> Block' |
| 187 | cfg.swift:187:3:197:3 | IfExpr | 'IfExpr -V x -> 2 -^ ... > ...' |
Expand Down
Loading