@@ -31,6 +31,22 @@ static bool isTypesEqual(TypeInfo t1, TypeInfo t2) {
3131 return true;
3232}
3333
34+ static TypeInfo duplicateType (TypeInfo type ) {
35+ TypeInfo copy = type ;
36+ if (type .name ) copy .name = strdup (type .name );
37+ if (type .returnType ) {
38+ copy .returnType = (TypeInfo * )malloc (sizeof (TypeInfo ));
39+ * copy .returnType = duplicateType (* type .returnType );
40+ }
41+ if (type .paramTypes ) {
42+ copy .paramTypes = (TypeInfo * )malloc (sizeof (TypeInfo ) * type .paramCount );
43+ for (int i = 0 ; i < type .paramCount ; i ++ ) {
44+ copy .paramTypes [i ] = duplicateType (type .paramTypes [i ]);
45+ }
46+ }
47+ return copy ;
48+ }
49+
3450
3551// --- Symbol Table Helpers ---
3652
@@ -46,6 +62,20 @@ static Scope* beginScope(TypeChecker* checker) {
4662 return scope ;
4763}
4864
65+ static void freeTypeInfoMembers (TypeInfo type ) {
66+ if (type .name ) free (type .name );
67+ if (type .returnType ) {
68+ freeTypeInfoMembers (* type .returnType );
69+ free (type .returnType );
70+ }
71+ if (type .paramTypes ) {
72+ for (int i = 0 ; i < type .paramCount ; i ++ ) {
73+ freeTypeInfoMembers (type .paramTypes [i ]);
74+ }
75+ free (type .paramTypes );
76+ }
77+ }
78+
4979static void endScope (TypeChecker * checker ) {
5080 Scope * scope = checker -> currentScope ;
5181 checker -> currentScope = scope -> parent ;
@@ -55,10 +85,8 @@ static void endScope(TypeChecker* checker) {
5585 Symbol * sym = scope -> table [i ];
5686 while (sym ) {
5787 Symbol * next = sym -> next ;
58- // Free members of TypeInfo
59- if (sym -> type .name ) free (sym -> type .name );
60- if (sym -> type .paramTypes ) free (sym -> type .paramTypes );
61- free (sym -> type .returnType );
88+ // Free members of TypeInfo recursively
89+ freeTypeInfoMembers (sym -> type );
6290 free (sym );
6391 sym = next ;
6492 }
@@ -81,7 +109,7 @@ static void defineSymbol(TypeChecker* checker, const char* name, TypeInfo type)
81109
82110 Symbol * sym = (Symbol * )malloc (sizeof (Symbol ));
83111 sym -> name = (char * )name ; // Weak reference
84- sym -> type = type ;
112+ sym -> type = duplicateType ( type ) ;
85113 sym -> next = scope -> table [idx ];
86114 scope -> table [idx ] = sym ;
87115}
@@ -95,8 +123,23 @@ static void updateSymbol(TypeChecker* checker, const char* name, TypeInfo type)
95123 Symbol * sym = scope -> table [idx ];
96124 while (sym ) {
97125 if (strcmp (sym -> name , name ) == 0 ) {
126+ // Free old type members before replacing
127+ if (sym -> type .name ) free (sym -> type .name );
128+ if (sym -> type .paramTypes ) {
129+ for (int j = 0 ; j < sym -> type .paramCount ; j ++ ) {
130+ // Deep free if needed? For now we only have 1 level of paramTypes as simple array
131+ // but let's be consistent.
132+ }
133+ free (sym -> type .paramTypes );
134+ }
135+ if (sym -> type .returnType ) {
136+ // Recursive free would be better, but let's just free the pointer for now
137+ // as we don't have a full freeTypeInfo yet.
138+ free (sym -> type .returnType );
139+ }
140+
98141 // Update the type (including taint status)
99- sym -> type = type ;
142+ sym -> type = duplicateType ( type ) ;
100143 return ;
101144 }
102145 sym = sym -> next ;
@@ -337,9 +380,9 @@ static TypeInfo checkExpr(TypeChecker* checker, Expr* expr) {
337380
338381 if (callee .kind == TYPE_FUNCTION || callee .kind == TYPE_CLASS ) {
339382 if (callee .returnType ) {
340- result = * callee .returnType ; // Copy return type
383+ result = duplicateType ( * callee .returnType ) ; // Deep copy return type
341384 } else if (callee .kind == TYPE_CLASS ) {
342- result = callee ; // Constructor returns class instance
385+ result = duplicateType ( callee ) ; // Constructor returns class instance
343386 }
344387 // TODO: Check argument types against callee.paramTypes
345388 } else if (callee .kind == TYPE_UNKNOWN ) {
0 commit comments