bug fix #2568
This commit is contained in:
parent
daf20fdb99
commit
7e18d092e8
9
TestSuite/errors/err0442.pas
Normal file
9
TestSuite/errors/err0442.pas
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
//!Использование exit, break и continue в блоке finally недопустимо
|
||||
begin
|
||||
for var i := 1 to 10 do
|
||||
try
|
||||
|
||||
finally
|
||||
break;
|
||||
end;
|
||||
end.
|
||||
9
TestSuite/errors/err0443.pas
Normal file
9
TestSuite/errors/err0443.pas
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
//!Использование exit, break и continue в блоке finally недопустимо
|
||||
begin
|
||||
for var i := 1 to 10 do
|
||||
try
|
||||
|
||||
finally
|
||||
continue;
|
||||
end;
|
||||
end.
|
||||
8
TestSuite/errors/err0444.pas
Normal file
8
TestSuite/errors/err0444.pas
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
//!Использование exit, break и continue в блоке finally недопустимо
|
||||
begin
|
||||
try
|
||||
|
||||
finally
|
||||
exit;
|
||||
end;
|
||||
end.
|
||||
16
TestSuite/errors/err0445.pas
Normal file
16
TestSuite/errors/err0445.pas
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//!Использование exit, break и continue в блоке finally недопустимо
|
||||
begin
|
||||
var k := 0;
|
||||
for var i := 1 to 3 do
|
||||
try
|
||||
|
||||
finally
|
||||
for var j := 1 to 10 do
|
||||
begin
|
||||
k := j;
|
||||
exit;
|
||||
end;
|
||||
|
||||
end;
|
||||
assert(k = 1);
|
||||
end.
|
||||
16
TestSuite/errors/err0446.pas
Normal file
16
TestSuite/errors/err0446.pas
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//!Использование exit, break и continue в блоке finally недопустимо
|
||||
begin
|
||||
var k := 0;
|
||||
for var i := 1 to 3 do
|
||||
try
|
||||
|
||||
finally
|
||||
for var j := 1 to 10 do
|
||||
begin
|
||||
k := j;
|
||||
continue;
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
assert(k = 1);
|
||||
end.
|
||||
20
TestSuite/errors/err0447.pas
Normal file
20
TestSuite/errors/err0447.pas
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//!Использование exit, break и continue в блоке finally недопустимо
|
||||
begin
|
||||
var k := 0;
|
||||
for var i := 1 to 3 do
|
||||
try
|
||||
|
||||
finally
|
||||
for var j := 1 to 10 do
|
||||
begin
|
||||
try
|
||||
k := j;
|
||||
continue;
|
||||
finally
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
assert(k = 1);
|
||||
end.
|
||||
15
TestSuite/exceptions5.pas
Normal file
15
TestSuite/exceptions5.pas
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
begin
|
||||
var k := 0;
|
||||
for var i := 1 to 3 do
|
||||
try
|
||||
|
||||
finally
|
||||
for var j := 1 to 10 do
|
||||
begin
|
||||
k := j;
|
||||
break;
|
||||
end;
|
||||
|
||||
end;
|
||||
assert(k = 1);
|
||||
end.
|
||||
|
|
@ -649,7 +649,7 @@ namespace TreeConverter.LambdaExpressions.Closure
|
|||
_visitor.convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elemType, _visitor.get_location(_foreach_stmt.identifier));
|
||||
|
||||
var fn = new foreach_node(vdn, inWhat, null, _visitor.get_location(_foreach_stmt));
|
||||
_visitor.context.cycle_stack.push(fn);
|
||||
_visitor.context.enter_in_cycle(fn);
|
||||
_visitor.context.loop_var_stack.Push(vdn);
|
||||
|
||||
ProcessNode(_foreach_stmt.in_what);
|
||||
|
|
@ -664,7 +664,7 @@ namespace TreeConverter.LambdaExpressions.Closure
|
|||
|
||||
_visitor.context.loop_var_stack.Pop();
|
||||
_visitor.convertion_data_and_alghoritms.statement_list_stack.pop();
|
||||
_visitor.context.cycle_stack.pop();
|
||||
_visitor.context.leave_cycle();
|
||||
|
||||
_currentTreeNode = _currentTreeNode.ParentNode;
|
||||
}
|
||||
|
|
@ -727,7 +727,7 @@ namespace TreeConverter.LambdaExpressions.Closure
|
|||
{
|
||||
fn.bool_cycle = true;
|
||||
}
|
||||
_visitor.context.cycle_stack.push(fn);
|
||||
_visitor.context.enter_in_cycle(fn);
|
||||
_visitor.context.loop_var_stack.Push(vdn);
|
||||
|
||||
nodesToProcess.Add(_for_node.initial_value);
|
||||
|
|
@ -746,7 +746,7 @@ namespace TreeConverter.LambdaExpressions.Closure
|
|||
}
|
||||
ProcessNode(_for_node.statements);
|
||||
|
||||
_visitor.context.cycle_stack.pop();
|
||||
_visitor.context.leave_cycle();
|
||||
_visitor.context.loop_var_stack.Pop();
|
||||
_visitor.convertion_data_and_alghoritms.statement_list_stack.pop();
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
TreeRealization.for_node forNode = new TreeRealization.for_node(null, sn_while, sn_init_while, sn_inc, null, get_location(_for_node));
|
||||
if (vdn.type == SystemLibrary.SystemLibrary.bool_type)
|
||||
forNode.bool_cycle = true;
|
||||
context.cycle_stack.push(forNode);
|
||||
context.enter_in_cycle(forNode);
|
||||
context.loop_var_stack.Push(vdn);
|
||||
statements_list slst = new statements_list(get_location(_for_node.statements));
|
||||
convertion_data_and_alghoritms.statement_list_stack_push(slst);
|
||||
|
|
@ -172,7 +172,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
forNode.body = slst;
|
||||
}
|
||||
|
||||
context.cycle_stack.pop();
|
||||
context.leave_cycle();
|
||||
context.loop_var_stack.Pop();
|
||||
head_stmts = convertion_data_and_alghoritms.statement_list_stack.pop();
|
||||
head_stmts.statements.AddElement(forNode);
|
||||
|
|
|
|||
|
|
@ -46,13 +46,13 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
foreach_node foreachNode = new foreach_node(foreachVariable, foreachCollection, null, get_location(_foreach_stmt));
|
||||
|
||||
context.cycle_stack.push(foreachNode);
|
||||
context.enter_in_cycle(foreachNode);
|
||||
context.loop_var_stack.Push(foreachVariable);
|
||||
context.enter_code_block_with_bind();
|
||||
statement_node body = convert_strong(_foreach_stmt.stmt);
|
||||
context.leave_code_block();
|
||||
context.loop_var_stack.Pop();
|
||||
context.cycle_stack.pop();
|
||||
context.leave_cycle();
|
||||
|
||||
sl = convertion_data_and_alghoritms.statement_list_stack.pop();
|
||||
|
||||
|
|
|
|||
|
|
@ -3958,6 +3958,37 @@ namespace PascalABCCompiler.TreeConverter
|
|||
_block_stack.Push(new code_block(null));
|
||||
}
|
||||
|
||||
int finally_blocks_depth = 0;
|
||||
bool disable_finally_control_break_check = false;
|
||||
|
||||
public void enter_finally_block()
|
||||
{
|
||||
finally_blocks_depth++;
|
||||
disable_finally_control_break_check = false;
|
||||
}
|
||||
|
||||
public void leave_finally_block()
|
||||
{
|
||||
finally_blocks_depth--;
|
||||
}
|
||||
|
||||
public bool in_finally_block(bool ignore_disable_finally_control_break_check = false)
|
||||
{
|
||||
return (!disable_finally_control_break_check || ignore_disable_finally_control_break_check) && finally_blocks_depth > 0;
|
||||
}
|
||||
|
||||
public void enter_in_cycle(statement_node stmt)
|
||||
{
|
||||
cycle_stack.push(stmt);
|
||||
disable_finally_control_break_check = true;
|
||||
}
|
||||
|
||||
public void leave_cycle()
|
||||
{
|
||||
cycle_stack.pop();
|
||||
disable_finally_control_break_check = false;
|
||||
}
|
||||
|
||||
//Убирает блок со стека
|
||||
public void leave_code_block()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1766,6 +1766,10 @@ namespace PascalABCCompiler.TreeConverter
|
|||
{
|
||||
AddError(new BreakStatementWithoutComprehensiveCycle(call_location));
|
||||
}
|
||||
if (context.in_finally_block())
|
||||
{
|
||||
AddError(call_location, "EXIT_BREAK_CONTINUE_IN_FINALLY_BLOCK");
|
||||
}
|
||||
statement_node sn = context.cycle_stack.top();
|
||||
switch (sn.semantic_node_type)
|
||||
{
|
||||
|
|
@ -1803,6 +1807,10 @@ namespace PascalABCCompiler.TreeConverter
|
|||
{
|
||||
AddError(new ContinueStatementWithoutComprehensiveCycle(call_location));
|
||||
}
|
||||
if (context.in_finally_block())
|
||||
{
|
||||
AddError(call_location, "EXIT_BREAK_CONTINUE_IN_FINALLY_BLOCK");
|
||||
}
|
||||
statement_node sn = context.cycle_stack.top();
|
||||
switch (sn.semantic_node_type)
|
||||
{
|
||||
|
|
@ -1836,6 +1844,10 @@ namespace PascalABCCompiler.TreeConverter
|
|||
{
|
||||
return null;
|
||||
}
|
||||
if (context.in_finally_block(true))
|
||||
{
|
||||
AddError(call_location, "EXIT_BREAK_CONTINUE_IN_FINALLY_BLOCK");
|
||||
}
|
||||
if (!TreeConverter.SemanticRules.EnableExitProcedure)
|
||||
AddError(new TreeConverter.UndefinedNameReference(TreeConverter.compiler_string_consts.exit_procedure_name, call_location));
|
||||
return new exit_procedure(call_location);
|
||||
|
|
@ -1932,7 +1944,9 @@ namespace PascalABCCompiler.TreeConverter
|
|||
statements_list stm = new statements_list(null);
|
||||
SyntaxTree.try_handler_finally try_hndlr_finally = _try_stmt.handler as SyntaxTree.try_handler_finally;
|
||||
context.enter_code_block_without_bind();
|
||||
context.enter_finally_block();
|
||||
statement_node finally_stmt = convert_strong(try_hndlr_finally.stmt_list);
|
||||
context.leave_finally_block();
|
||||
context.leave_code_block();
|
||||
stm.statements.AddElement(finally_stmt);
|
||||
|
||||
|
|
@ -1956,7 +1970,15 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if (try_handler_finally != null)
|
||||
{
|
||||
context.enter_code_block_without_bind();
|
||||
finally_st = convert_strong(try_handler_finally.stmt_list);
|
||||
context.enter_finally_block();
|
||||
try
|
||||
{
|
||||
finally_st = convert_strong(try_handler_finally.stmt_list);
|
||||
}
|
||||
finally
|
||||
{
|
||||
context.leave_finally_block();
|
||||
}
|
||||
context.leave_code_block();
|
||||
}
|
||||
try_block tb = new try_block(try_statements, finally_st, efl, loc);
|
||||
|
|
@ -15811,7 +15833,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
|
||||
while_node wn = new while_node(expr, get_location(_while_node));
|
||||
context.cycle_stack.push(wn);
|
||||
context.enter_in_cycle(wn);
|
||||
|
||||
statements_list sl = new statements_list(get_location(_while_node.statements));
|
||||
convertion_data_and_alghoritms.statement_list_stack_push(sl);
|
||||
|
|
@ -15828,14 +15850,14 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
|
||||
wn.body = st;
|
||||
context.cycle_stack.pop();
|
||||
context.leave_cycle();
|
||||
return_value(wn);
|
||||
}
|
||||
|
||||
public override void visit(SyntaxTree.repeat_node _repeat_node)
|
||||
{
|
||||
repeat_node rep = new repeat_node(get_location(_repeat_node));
|
||||
context.cycle_stack.push(rep);
|
||||
context.enter_in_cycle(rep);
|
||||
|
||||
statements_list sl = new statements_list(get_location(_repeat_node.statements));
|
||||
convertion_data_and_alghoritms.statement_list_stack_push(sl);
|
||||
|
|
@ -15861,7 +15883,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
try_convert_typed_expression_to_function_call(ref expr, true);
|
||||
rep.condition = expr;
|
||||
}
|
||||
context.cycle_stack.pop();
|
||||
context.leave_cycle();
|
||||
return_value(rep);
|
||||
}
|
||||
|
||||
|
|
@ -20005,7 +20027,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
CheckToEmbeddedStatementCannotBeADeclaration(node.stmt);
|
||||
|
||||
for_node fn = new for_node(sn_init, sn_cond, null, sn_next, null, get_location(node));
|
||||
context.cycle_stack.push(fn);
|
||||
context.enter_in_cycle(fn);
|
||||
|
||||
statements_list slst = new statements_list(get_location(node.stmt));
|
||||
convertion_data_and_alghoritms.statement_list_stack_push(slst);
|
||||
|
|
@ -20021,7 +20043,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
fn.body = slst;
|
||||
}
|
||||
|
||||
context.cycle_stack.pop();
|
||||
context.leave_cycle();
|
||||
|
||||
head_stmts = convertion_data_and_alghoritms.statement_list_stack.pop();
|
||||
head_stmts.statements.AddElement(fn);
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ AMBIGUOUS_DELEGATES=Ambiguous delegates detected
|
|||
EXPECTED_INTERFACE=Interface expected
|
||||
EXPECTED_PROPERTY=Property expected
|
||||
NON_PUBLIC_RECORD_CONSTRUCTORS_NOT_ALLOWED=Records can not have non-public default constructor
|
||||
EXIT_BREAK_CONTINUE_IN_FINALLY_BLOCK=exit, break and continue are not allowed in finally
|
||||
%PREFIX%=COMPILATIONERROR_
|
||||
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Unit expected, library found
|
||||
ASSEMBLY_{0}_READING_ERROR=Error by reading assembly '{0}'
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ AMBIGUOUS_DELEGATES=Невозможно выбрать конкретный д
|
|||
EXPECTED_INTERFACE=Ожидалось имя интерфейса
|
||||
EXPECTED_PROPERTY=Ожидалось свойство
|
||||
NON_PUBLIC_RECORD_CONSTRUCTORS_NOT_ALLOWED=Записи могут иметь только публичный конструктор по умолчанию
|
||||
EXIT_BREAK_CONTINUE_IN_FINALLY_BLOCK=Использование exit, break и continue в блоке finally недопустимо
|
||||
%PREFIX%=COMPILATIONERROR_
|
||||
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Ожидался модуль, а встречена библиотека
|
||||
ASSEMBLY_{0}_READING_ERROR=Ошибка при чтении сборки '{0}'
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ AMBIGUOUS_DELEGATES=Невозможно выбрать конкретный д
|
|||
EXPECTED_INTERFACE=Ожидалось имя интерфейса
|
||||
EXPECTED_PROPERTY=Ожидалось свойство
|
||||
NON_PUBLIC_RECORD_CONSTRUCTORS_NOT_ALLOWED=Записи могут иметь только публичный конструктор по умолчанию
|
||||
EXIT_BREAK_CONTINUE_IN_FINALLY_BLOCK=Использование exit, break и continue в блоке finally недопустимо
|
||||
%PREFIX%=COMPILATIONERROR_
|
||||
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Очікувався модуль, а зустріли бібліотеку
|
||||
ASSEMBLY_{0}_READING_ERROR=Помилка при читанні збірки '{0}'
|
||||
|
|
|
|||
Loading…
Reference in a new issue