diff options
author | Jon Olav Hauglid <jon.hauglid@oracle.com> | 2012-01-09 11:28:02 +0100 |
---|---|---|
committer | Jon Olav Hauglid <jon.hauglid@oracle.com> | 2012-01-09 11:28:02 +0100 |
commit | 6c1bbb50cb9ee124e762f66004a3daad297e6d6f (patch) | |
tree | 72ca1c71906da75727e51474b01b58c7a6f16892 /sql/sp_head.cc | |
parent | 43ea968d456d08e2cd9719608d3b73e2b90963d1 (diff) | |
download | mariadb-git-6c1bbb50cb9ee124e762f66004a3daad297e6d6f.tar.gz |
Backport from mysql-trunk of:
------------------------------------------------------------
revno: 3258
committer: Jon Olav Hauglid <jon.hauglid@oracle.com>
branch nick: mysql-trunk-bug12663165
timestamp: Thu 2011-07-14 10:05:12 +0200
message:
Bug#12663165 SP DEAD CODE REMOVAL DOESN'T UNDERSTAND CONTINUE HANDLERS
When stored routines are loaded, a simple optimizer tries to locate
and remove dead code. The problem was that this dead code removal
did not work correctly with CONTINUE handlers.
If a statement triggers a CONTINUE handler, the following statement
will be executed after the handler statement has completed. This
means that the following statement is not dead code even if the
previous statement unconditionally alters control flow. This fact
was lost on the dead code removal routine, which ended up with
removing instructions that could have been executed. This could
then lead to assertions, crashes and generally bad behavior when
the stored routine was executed.
This patch fixes the problem by marking as live code all stored
routine instructions that are in the same scope as a CONTINUE handler.
Test case added to sp.test.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 8bea0be0f56..dec76615ec7 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3356,6 +3356,23 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp, List<sp_instr> *leads) m_optdest= sp->get_instr(m_dest); } sp->add_mark_lead(m_dest, leads); + + /* + For continue handlers, all instructions in the scope of the handler + are possible leads. For example, the instruction after freturn might + be executed if the freturn triggers the condition handled by the + continue handler. + + m_dest marks the start of the handler scope. It's added as a lead + above, so we start on m_dest+1 here. + m_opt_hpop is the hpop marking the end of the handler scope. + */ + if (m_type == SP_HANDLER_CONTINUE) + { + for (uint scope_ip= m_dest+1; scope_ip <= m_opt_hpop; scope_ip++) + sp->add_mark_lead(scope_ip, leads); + } + return m_ip+1; } |