@@ -132,7 +132,6 @@ bool typecheck_var_decl(AstNode *node, Scope *scope, ArenaAllocator *arena) {
132132 bool is_public = node -> stmt .var_decl .is_public ;
133133 bool is_mutable = node -> stmt .var_decl .is_mutable ;
134134
135- // Track memory allocation
136135 // Track memory allocation
137136 if (initializer && contains_alloc_expression (initializer )) {
138137 StaticMemoryAnalyzer * analyzer = get_static_analyzer (scope );
@@ -178,6 +177,7 @@ bool typecheck_var_decl(AstNode *node, Scope *scope, ArenaAllocator *arena) {
178177 }
179178
180179 // Track ownership transfer from function return values
180+ // CRITICAL FIX: Only track if the returned type is a POINTER
181181 if (initializer && initializer -> type == AST_EXPR_CALL ) {
182182 AstNode * callee = initializer -> expr .call .callee ;
183183 Symbol * func_symbol = NULL ;
@@ -194,14 +194,27 @@ bool typecheck_var_decl(AstNode *node, Scope *scope, ArenaAllocator *arena) {
194194 }
195195
196196 // If function returns ownership, track as allocation
197+ // BUT ONLY if the return type is actually a pointer
197198 if (func_symbol && func_symbol -> returns_ownership ) {
198- StaticMemoryAnalyzer * analyzer = get_static_analyzer (scope );
199- if (analyzer ) {
200- const char * func_name = get_current_function_name (scope );
201- static_memory_track_alloc (analyzer , node -> line , node -> column , name ,
202- func_name , g_tokens , g_token_count ,
203- g_file_path );
199+ // Get the actual return type
200+ AstNode * return_type = NULL ;
201+ if (func_symbol -> type && func_symbol -> type -> type == AST_TYPE_FUNCTION ) {
202+ return_type = func_symbol -> type -> type_data .function .return_type ;
203+ }
204+
205+ // CRITICAL: Only track if return type is a pointer
206+ if (return_type && is_pointer_type (return_type )) {
207+ StaticMemoryAnalyzer * analyzer = get_static_analyzer (scope );
208+ if (analyzer ) {
209+ const char * func_name = get_current_function_name (scope );
210+ static_memory_track_alloc (analyzer , node -> line , node -> column , name ,
211+ func_name , g_tokens , g_token_count ,
212+ g_file_path );
213+ }
204214 }
215+ // If return type is a struct with pointer fields, we DON'T track the
216+ // struct itself The struct is a value type, not a heap allocation Only
217+ // the pointer FIELDS need to be freed (which the user handles with defer)
205218 }
206219 }
207220
0 commit comments