aboutsummaryrefslogtreecommitdiff
path: root/src/check_stmt.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2025-04-07 11:57:55 +0100
committergingerBill <bill@gingerbill.org>2025-04-07 11:57:55 +0100
commit77b5eebf8ce090839713fc59fe0f60045524043f (patch)
tree6426a52f779090381785c3e7a2bab520bfcb3ffe /src/check_stmt.cpp
parentbee158d53a877004de7fb15fa46ae235d42f9dfb (diff)
Add trivial sanity check for assigning to return values within `defer` #5011
Diffstat (limited to 'src/check_stmt.cpp')
-rw-r--r--src/check_stmt.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index e81996566..1b44ff4d7 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -2755,6 +2755,47 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
if (ctx->decl) {
ctx->decl->defer_used += 1;
}
+
+ // NOTE(bill): Handling errors/warnings
+
+ Ast *stmt = ds->stmt;
+ Ast *original_stmt = stmt;
+
+ bool is_singular = true;
+ while (is_singular && stmt->kind == Ast_BlockStmt) {
+ Ast *inner_stmt = nullptr;
+ for (Ast *s : stmt->BlockStmt.stmts) {
+ if (s->kind == Ast_EmptyStmt) {
+ continue;
+ }
+ if (inner_stmt != nullptr) {
+ is_singular = false;
+ break;
+ }
+ inner_stmt = s;
+ }
+
+ if (inner_stmt != nullptr) {
+ stmt = inner_stmt;
+ }
+ }
+ if (!is_singular) {
+ stmt = original_stmt;
+ }
+
+ switch (stmt->kind) {
+ case_ast_node(as, AssignStmt, stmt);
+ if (as->op.kind != Token_Eq) {
+ break;
+ }
+ for (Ast *lhs : as->lhs) {
+ Entity *e = entity_of_node(lhs);
+ if (e && e->flags & EntityFlag_Result) {
+ error(lhs, "Assignments to named return values within 'defer' will not affect the value that is returned");
+ }
+ }
+ case_end;
+ }
}
case_end;