1+ use crate :: compiler:: Compiler ;
12use crate :: compiler:: ast:: ssa_ir:: OpCode :: Push ;
23use crate :: compiler:: ast:: ssa_ir:: Operand :: ImmNumFlot ;
34use crate :: compiler:: ast:: ssa_ir:: ValueGuessType :: {
@@ -6,8 +7,9 @@ use crate::compiler::ast::ssa_ir::ValueGuessType::{
67use crate :: compiler:: ast:: ssa_ir:: { OpCode , OpCodeTable , Operand , ValueAlloc , ValueGuessType } ;
78use crate :: compiler:: ast:: { ASTExprTree , ExprOp } ;
89use crate :: compiler:: lexer:: { Token , TokenType } ;
10+ use crate :: compiler:: lints:: Lint :: SyncRecursion ;
911use crate :: compiler:: parser:: ParserError ;
10- use crate :: compiler:: parser:: symbol_table:: ElementType ;
12+ use crate :: compiler:: parser:: symbol_table:: { ContextType , ElementType } ;
1113use crate :: compiler:: semantic:: Semantic ;
1214use crate :: compiler:: semantic:: optimizer:: { expr_optimizer, unary_optimizer} ;
1315use slotmap:: DefaultKey ;
@@ -352,7 +354,23 @@ fn lower_ref(
352354 } ;
353355
354356 if let Some ( base) = base {
355- let full_path = format_smolstr ! ( "{}/{}" , base, token. text( ) ) ;
357+ let full_path = format_smolstr ! ( "{base}/{}" , token. text( ) ) ;
358+
359+ if file_base == base && let Some ( context) = semantic
360+ . compiler_data ( )
361+ . symbol_table
362+ . get_context ( & ContextType :: Func )
363+ && context. func_sync
364+ && context. func_name . as_str ( ) == token. text ( )
365+ {
366+ Compiler :: warning_info_expr (
367+ semantic. file ,
368+ "unsafe recursion in synchronized function." ,
369+ right_tree,
370+ SyncRecursion ,
371+ ) ;
372+ }
373+
356374 opcode_table. add_opcode ( Push ( None , Operand :: Reference ( full_path) ) ) ;
357375 return Ok ( ( token. text ( ) . to_smolstr ( ) , opcode_table) ) ;
358376 }
@@ -578,6 +596,23 @@ fn expr_call(
578596 . next ( )
579597 . unwrap_or ( semantic. file . name . as_str ( ) ) ;
580598 let full_path = format_smolstr ! ( "{file_base}/{path}" ) ;
599+
600+ // 检查同步函数递归调用
601+ if let Some ( context) = semantic
602+ . compiler_data ( )
603+ . symbol_table
604+ . get_context ( & ContextType :: Func )
605+ && context. func_name == path
606+ && context. func_sync
607+ {
608+ Compiler :: warning_info_expr (
609+ semantic. file ,
610+ "unsafe recursion in synchronized function." ,
611+ name,
612+ SyncRecursion ,
613+ ) ;
614+ }
615+
581616 opcode_table. add_opcode ( Push ( None , Operand :: Reference ( full_path) ) ) ;
582617 opcode_table. add_opcode ( OpCode :: Call ( None , path. clone ( ) ) ) ;
583618 Ok ( ( Operand :: Call ( path) , Unknown , opcode_table) )
0 commit comments