diff --git a/Compiler/PCU/PCUFileFormatVersion.cs b/Compiler/PCU/PCUFileFormatVersion.cs index c66338ea8..dddfb3105 100644 --- a/Compiler/PCU/PCUFileFormatVersion.cs +++ b/Compiler/PCU/PCUFileFormatVersion.cs @@ -6,6 +6,6 @@ namespace PascalABCCompiler.PCU { public static class PCUFileFormatVersion { - public static System.Int16 Version = 105; + public static System.Int16 Version = 106; } } diff --git a/Compiler/PCU/PCUReader.cs b/Compiler/PCU/PCUReader.cs index c855fe1af..d1281d1b3 100644 --- a/Compiler/PCU/PCUReader.cs +++ b/Compiler/PCU/PCUReader.cs @@ -3141,7 +3141,10 @@ namespace PascalABCCompiler.PCU filter_type = GetTypeReference(); local_block_variable_reference exception_var = null; if (CanReadObject()) + { + CreateLocalBlockVariable(null); exception_var = (local_block_variable_reference)CreateLocalBlockVariableReference(); + } efl.AddElement(new exception_filter(filter_type,exception_var,CreateStatement(),ReadDebugInfo())); } return new try_block(try_statements, finally_statements, efl, null); diff --git a/Compiler/PCU/PCUWriter.cs b/Compiler/PCU/PCUWriter.cs index f402ef6c1..e412d5917 100644 --- a/Compiler/PCU/PCUWriter.cs +++ b/Compiler/PCU/PCUWriter.cs @@ -3190,7 +3190,10 @@ namespace PascalABCCompiler.PCU if (CanWriteObject(ef.filter_type)) WriteTypeReference(ef.filter_type); if (CanWriteObject(ef.exception_var)) + { + VisitLocalBlockVariable(ef.exception_var.var); VisitLocalBlockVariableReference(ef.exception_var); + } VisitStatement(ef.exception_handler); WriteDebugInfo(ef.location); } diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 536b15d6b..cd8f81ede 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -5616,9 +5616,14 @@ namespace PascalABCCompiler.NETGenerator else typ = TypeFactory.ExceptionType; il.BeginCatchBlock(typ); + if (iefbn.ExceptionInstance != null) { - il.Emit(OpCodes.Stloc, helper.GetVariable(iefbn.ExceptionInstance.Variable).lb); + LocalBuilder lb = il.DeclareLocal(typ); + helper.AddVariable(iefbn.ExceptionInstance.Variable, lb); + if (save_debug_info && iefbn.ExceptionInstance.Location != null) + lb.SetLocalSymInfo(iefbn.ExceptionInstance.Variable.name + ":" + iefbn.ExceptionInstance.Location.begin_line_num + ":" + iefbn.ExceptionInstance.Location.end_line_num); + il.Emit(OpCodes.Stloc, lb); } else { diff --git a/TestSuite/exceptions2.pas b/TestSuite/exceptions2.pas new file mode 100644 index 000000000..c1d8225f9 --- /dev/null +++ b/TestSuite/exceptions2.pas @@ -0,0 +1,16 @@ +type + MyException1 = class(Exception); + MyException2 = class(Exception); + IncorrectInputException = class(Exception); + +begin + var s := ''; + try + raise new MyException1('EXCEPTION2!!'); + except + on e: IncorrectInputException do writeln(e.Message); + on e: MyException1 do s := e.Message; + on e: MyException2 do writeln(e.Message); + end; + assert(s = 'EXCEPTION2!!'); +end. \ No newline at end of file diff --git a/TestSuite/units/u_exceptions2.pas b/TestSuite/units/u_exceptions2.pas new file mode 100644 index 000000000..05a3667c6 --- /dev/null +++ b/TestSuite/units/u_exceptions2.pas @@ -0,0 +1,18 @@ +unit u_exceptions2; + +type + MyException1 = class(Exception); + MyException2 = class(Exception); + IncorrectInputException = class(Exception); + +begin + var s := ''; + try + raise new MyException1('EXCEPTION2!!'); + except + on e: IncorrectInputException do writeln(e.Message); + on e: MyException1 do s := e.Message; + on e: MyException2 do writeln(e.Message); + end; + assert(s = 'EXCEPTION2!!'); +end. \ No newline at end of file diff --git a/TestSuite/usesunits/use_exceptions2.pas b/TestSuite/usesunits/use_exceptions2.pas new file mode 100644 index 000000000..87e2cecce --- /dev/null +++ b/TestSuite/usesunits/use_exceptions2.pas @@ -0,0 +1 @@ +uses u_exceptions2; begin end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/compilation_context.cs b/TreeConverter/TreeConversion/compilation_context.cs index b0f19a5f9..e4a6fef5c 100644 --- a/TreeConverter/TreeConversion/compilation_context.cs +++ b/TreeConverter/TreeConversion/compilation_context.cs @@ -1653,7 +1653,7 @@ namespace PascalABCCompiler.TreeConverter return cf; } - public var_definition_node add_var_definition(string name, location loc, type_node tn, SemanticTree.polymorphic_state ps) + public var_definition_node add_var_definition(string name, location loc, type_node tn, SemanticTree.polymorphic_state ps, bool not_add_to_varlist=false) { check_name_free(name,loc); var_definition_node vdn=null; @@ -1681,7 +1681,8 @@ namespace PascalABCCompiler.TreeConverter } local_block_variable lv = new local_block_variable(name, tn, CurrentStatementList, loc); CurrentScope.AddSymbol(name, new SymbolInfo(lv)); - lv.block.local_variables.Add(lv); + if (!not_add_to_varlist) + lv.block.local_variables.Add(lv); if (tn == null) //Тип еще неизвестен, будем закрывать. var_defs.Add(lv); return lv; diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 18bedccf4..cbb11dc0b 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -1773,24 +1773,17 @@ namespace PascalABCCompiler.TreeConverter } current_catch_excep = new int_const_node(2,null);//create_constructor_call(filter_type, new expressions_list(), null); local_block_variable_reference lvr = null; - + statements_list sl = new statements_list(get_location(eh.statements)); + convertion_data_and_alghoritms.statement_list_stack_push(sl); context.enter_code_block_without_bind(); if (eh.variable != null) { - - context.check_name_redefinition = false; - - local_block_variable lbv = context.add_var_definition(eh.variable.name, get_location(eh.variable), filter_type, SemanticTree.polymorphic_state.ps_common) as local_block_variable; - context.check_name_redefinition = true; + local_block_variable lbv = context.add_var_definition(eh.variable.name, get_location(eh.variable), filter_type, SemanticTree.polymorphic_state.ps_common, true) as local_block_variable; lvr = new local_block_variable_reference(lbv, lbv.loc); } statement_node stm = convert_strong(eh.statements); context.leave_code_block(); - - /*if (eh.variable != null) - { - context.leave_scope(); - }*/ + sl = convertion_data_and_alghoritms.statement_list_stack.pop(); exception_filter ef = new exception_filter(filter_type, lvr, stm, get_location(eh)); efl.AddElement(ef); current_catch_excep = null;