diff options
| author | gingerBill <bill@gingerbill.org> | 2021-06-16 11:41:29 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-06-16 11:41:29 +0100 |
| commit | 8f57bb07991930f242ec4ab4d9fb3a851a4e9662 (patch) | |
| tree | 8c5c6ed78a4b59663ab0ee89bebb5785f1be4ba6 /src/check_stmt.cpp | |
| parent | 84a4188c7214fdf0270f9f835e626fa214a98df0 (diff) | |
Add unreachable detection for deferred statements in a scope which contains a diverging procedure call
```odin
{
defer foo(); // Unreachable defer statement due to diverging procedure call at the end of the current scope
os.exit(0);
}
```
Diffstat (limited to 'src/check_stmt.cpp')
| -rw-r--r-- | src/check_stmt.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index c6a9a5d93..4fdece852 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -27,6 +27,37 @@ bool is_diverging_stmt(Ast *stmt) { return t != nullptr && t->kind == Type_Proc && t->Proc.diverging; } +bool contains_deferred_call(Ast *node) { + if (node->viral_state_flags & ViralStateFlag_ContainsDeferredProcedure) { + return true; + } + switch (node->kind) { + case Ast_ExprStmt: + return contains_deferred_call(node->ExprStmt.expr); + case Ast_AssignStmt: + for_array(i, node->AssignStmt.rhs) { + if (contains_deferred_call(node->AssignStmt.rhs[i])) { + return true; + } + } + for_array(i, node->AssignStmt.lhs) { + if (contains_deferred_call(node->AssignStmt.lhs[i])) { + return true; + } + } + break; + case Ast_ValueDecl: + for_array(i, node->ValueDecl.values) { + if (contains_deferred_call(node->ValueDecl.values[i])) { + return true; + } + } + break; + } + + return false; +} + void check_stmt_list(CheckerContext *ctx, Slice<Ast *> const &stmts, u32 flags) { if (stmts.count == 0) { return; @@ -86,6 +117,19 @@ void check_stmt_list(CheckerContext *ctx, Slice<Ast *> const &stmts, u32 flags) } break; } + } else if (i+1 == max_non_constant_declaration) { + if (is_diverging_stmt(n)) { + for (isize j = 0; j < i; j++) { + Ast *stmt = stmts[j]; + if (stmt->kind == Ast_ValueDecl && !stmt->ValueDecl.is_mutable) { + + } else if (stmt->kind == Ast_DeferStmt) { + error(stmt, "Unreachable defer statement due to diverging procedure call at the end of the current scope"); + } else if (contains_deferred_call(stmt)) { + error(stmt, "Unreachable deferred procedure call due to a diverging procedure call at the end of the current scope"); + } + } + } } } } |