Author: dcoakley
Date: 2011-03-14 16:54:07 -0400 (Mon, 14 Mar 2011)
New Revision: 3518
Modified:
trunk/osprey/be/cg/eh_region.cxx
trunk/osprey/common/com/ir_bcom.cxx
trunk/osprey/ipa/local/ipl_summarize_template.h
trunk/osprey/ipa/main/optimize/ipo_main.cxx
trunk/osprey/wgen/wgen_stmt.cxx
Log:
Fix bug 735: C++ exception handling introduces false catch-all regions.
The root cause of the problem is that the two cases of catch-all (no
type filter) and cleanup (landing pad but no handler, and therefore no
type) are not distinguished in the compiler's internal representation
of EH info. A "hack" used to tell the difference in the CG appears to
have incorrect assummptions as it is easy to generate a test case where
a cleanup is marked as a catch-all in the output range table, and will
thus fail at runtime when the C++ runtime treats the cleanup landing
pad as if it were a handler.
This fix uses the formerly unused INITV "value" of INITVKIND_ONE to
definitively represent the catch-all case.
- In wgen, rename "append_catch_all" to "append_cleanup". This routine
appends a potential cleanup, not a catch-all marker. Use the type
filter value of INITVKIND_ONE for real catch-all regions.
- In the cg, the detection of catch-all is simplified and no guesswork
is needed.
- Adjust code that writes or copies the internal EH info to expect
INITVKIND_ONE as a possible type filter value.
Note: further changes to the TARG_IA64-specific implementation of
Create_INITO_For_Range_Table are required to complete the fix for
that target.
Approved by: Jian-Xin Lai
Modified: trunk/osprey/be/cg/eh_region.cxx
===================================================================
--- trunk/osprey/be/cg/eh_region.cxx 2011-03-13 00:52:39 UTC (rev 3517)
+++ trunk/osprey/be/cg/eh_region.cxx 2011-03-14 20:54:07 UTC (rev 3518)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Advanced Micro Devices, Inc. All Rights Reserved.
+ * Copyright (C) 2009, 2011 Advanced Micro Devices, Inc. All Rights Reserved.
*/
/*
@@ -1689,7 +1689,7 @@
for (INITV_IDX next = INITV_next(first); next; next = INITV_next(next)) {
// begin write action record (cinv, next)
int filter = 0;
- if (INITVKIND_ZERO != INITV_kind(next))
+ if (INITVKIND_VAL == INITV_kind(next))
filter = TCON_ival(INITV_tc_val(next));
if (filter > 0) { // handler
@@ -1859,34 +1859,18 @@
next_initv; next_initv=INITV_next (next_initv))
{
INITV_IDX action = New_INITV();
- int sym=0;
- if (INITV_kind(next_initv) != INITVKIND_ZERO)
+ // The special value INITVKIND_ONE represents a catch-all handler.
+ // A zero in the list means no handler, although there may still
+ // be a landing pad (cleanup).
+ int sym = 0;
+ bool catch_all = false;
+ if (INITV_kind(next_initv) == INITVKIND_ONE) {
+ FmtAssert (pad_label, ("Catch-all with no landing pad"));
+ catch_all = true;
+ }
+ else if (INITV_kind(next_initv) != INITVKIND_ZERO)
sym = TCON_uval(INITV_tc_val (next_initv));
- bool catch_all = false; // catch-all clause
- if (!sym)
- catch_all = (type_filter_map.find(sym) != type_filter_map.end());
- // if a region has eh specifications, we at least need:
- // 0 /* zero means zero */
- // 1 /* offset */
- // -filter /* eh spec typeinfo offset */
- // 0
- // But catch-all typeinfo is also zero. How to distinguish between
- // the first zero and a catch-all zero? The following hack is used:
- // if the next typeinfo is negative, then "zero means zero".
- if (catch_all && INITV_next (next_initv))
- {
- int next_sym = 0;
- INITV_IDX tmp_idx = INITV_next (next_initv);
- if (INITV_kind (tmp_idx) != INITVKIND_ZERO)
- next_sym = TCON_ival (INITV_tc_val (tmp_idx));
- if (next_sym < 0)
- catch_all = false;
- }
-
- // If there is no landing pad for this region, there should not be
- // a catch-all clause for it.
- if (catch_all && !pad_label) catch_all = false;
// action field
// Check if we have any action for this eh-region, if not, emit 0
// for action start marker.
Modified: trunk/osprey/common/com/ir_bcom.cxx
===================================================================
--- trunk/osprey/common/com/ir_bcom.cxx 2011-03-13 00:52:39 UTC (rev 3517)
+++ trunk/osprey/common/com/ir_bcom.cxx 2011-03-14 20:54:07 UTC (rev 3518)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Advanced Micro Devices, Inc. All Rights Reserved.
+ * Copyright (C) 2009, 2011 Advanced Micro Devices, Inc. All Rights Reserved.
*/
/*
@@ -495,7 +495,7 @@
INITV_IDX types = INITV_next (INITV_blk (INITO_val (WN_ereg_supp
(node))));
for (; types; types = INITV_next (types))
{
- if (INITV_kind (types) == INITVKIND_ZERO)
+ if (INITV_kind (types) != INITVKIND_VAL)
continue;
int index = TCON_uval (INITV_tc_val (types));
if (index <= 0) continue;
Modified: trunk/osprey/ipa/local/ipl_summarize_template.h
===================================================================
--- trunk/osprey/ipa/local/ipl_summarize_template.h 2011-03-13 00:52:39 UTC
(rev 3517)
+++ trunk/osprey/ipa/local/ipl_summarize_template.h 2011-03-14 20:54:07 UTC
(rev 3518)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2010 Advanced Micro Devices, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2011 Advanced Micro Devices, Inc. All Rights Reserved.
*/
/*
@@ -982,21 +982,34 @@
{
INITV_IDX st_entry = INITV_blk (blk);
ST_IDX st_idx = 0;
- if (INITV_kind (st_entry) != INITVKIND_ZERO)
+ bool catch_all = false;
+ if (INITV_kind (st_entry) == INITVKIND_ONE)
{
+ catch_all = true;
+ }
+ else if (INITV_kind (st_entry) != INITVKIND_ZERO)
+ {
st_idx = TCON_uval (INITV_tc_val (st_entry));
FmtAssert (st_idx != 0, ("Invalid st idx"));
}
- if (st_idx <= 0)
+ if (st_idx <= 0 && !catch_all)
{
blk = INITV_next (blk);
continue;
}
- INT32 index = Get_symbol_index (&St_Table [st_idx]);
INITV_IDX filter = INITV_next (st_entry); // for backup
- FmtAssert (index >= 0, ("Unexpected summary id for eh symbol"));
- INITV_Set_VAL (Initv_Table[st_entry], Enter_tcon (
- Host_To_Targ (MTYPE_U4, index)), 1);
+ if (!catch_all)
+ {
+ INT32 index = Get_symbol_index (&St_Table [st_idx]);
+ FmtAssert (index >= 0, ("Unexpected summary id for eh symbol"));
+ INITV_Set_VAL (Initv_Table[st_entry], Enter_tcon (
+ Host_To_Targ (MTYPE_U4, index)), 1);
+ }
+ else
+ {
+ // copy catch-all marker
+ INITV_Set_ONE (Initv_Table[st_entry], MTYPE_U4, 1);
+ }
Set_INITV_next (st_entry, filter);
blk = INITV_next (blk);
} while (blk);
@@ -1055,7 +1068,7 @@
for (; types; types = INITV_next (types))
{
int sym = 0;
- if (INITV_kind (types) != INITVKIND_ZERO)
+ if (INITV_kind (types) == INITVKIND_VAL)
sym = TCON_uval (INITV_tc_val (types));
if (sym > 0)
{
Modified: trunk/osprey/ipa/main/optimize/ipo_main.cxx
===================================================================
--- trunk/osprey/ipa/main/optimize/ipo_main.cxx 2011-03-13 00:52:39 UTC (rev
3517)
+++ trunk/osprey/ipa/main/optimize/ipo_main.cxx 2011-03-14 20:54:07 UTC (rev
3518)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 Advanced Micro Devices, Inc. All Rights Reserved.
+ * Copyright (C) 2008-2009, 2011 Advanced Micro Devices, Inc. All Rights
Reserved.
*/
/*
@@ -451,7 +451,7 @@
INITV_IDX types = INITV_next (INITV_blk (blk));
for (; types; types = INITV_next (types))
{
- if (INITV_kind (types) == INITVKIND_ZERO)
+ if (INITV_kind (types) != INITVKIND_VAL)
continue;
int index = TCON_uval (INITV_tc_val (types));
if (index <= 0) continue;
Modified: trunk/osprey/wgen/wgen_stmt.cxx
===================================================================
--- trunk/osprey/wgen/wgen_stmt.cxx 2011-03-13 00:52:39 UTC (rev 3517)
+++ trunk/osprey/wgen/wgen_stmt.cxx 2011-03-14 20:54:07 UTC (rev 3518)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2010 Advanced Micro Devices, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2011 Advanced Micro Devices, Inc. All Rights Reserved.
*/
/*
@@ -3080,8 +3080,13 @@
gs_t type = gs_handler_type(h);
ST_IDX st = 0;
- if (type) st = ST_st_idx (Get_ST (Get_typeinfo_var(type)));
- INITV_Set_VAL (Initv_Table[type_st], Enter_tcon (Host_To_Targ
(MTYPE_U4, st)), 1);
+ if (type)
+ {
+ st = ST_st_idx (Get_ST (Get_typeinfo_var(type)));
+ INITV_Set_VAL (Initv_Table[type_st], Enter_tcon (Host_To_Targ
(MTYPE_U4, st)), 1);
+ }
+ else // catch-all handler
+ INITV_Set_ONE (Initv_Table[type_st], MTYPE_U4, 1);
if (prev_type_st) Set_INITV_next (prev_type_st, type_st);
else start = type_st;
@@ -3178,17 +3183,18 @@
else iv = eh_filter;
}
+// Zero represents no handler, but possibly an associated landing pad.
static void
-append_catch_all (INITV_IDX& iv)
+append_cleanup (INITV_IDX& iv)
{
INITV_IDX tmp = iv;
while (tmp && INITV_next (tmp))
tmp = INITV_next (tmp);
- INITV_IDX catch_all = New_INITV();
- INITV_Set_VAL (Initv_Table[catch_all], Enter_tcon (Host_To_Targ (MTYPE_U4,
0)), 1);
- if (tmp) Set_INITV_next (tmp, catch_all);
- else iv = catch_all;
+ INITV_IDX cleanup = New_INITV();
+ INITV_Set_VAL (Initv_Table[cleanup], Enter_tcon (Host_To_Targ (MTYPE_U4,
0)), 1);
+ if (tmp) Set_INITV_next (tmp, cleanup);
+ else iv = cleanup;
}
// current: D1 D2 D3, prev: D1 D2 => emit D3 for current, goto prev
@@ -3285,11 +3291,11 @@
Set_PU_needs_manual_unwinding (Get_Current_PU());
// the following 2 calls can change 'iv'.
// NOTE: CG expects a zero before eh-spec filter
- bool catch_all_appended = false;
+ bool cleanup_appended = false;
if (PU_needs_manual_unwinding (Get_Current_PU()))
{
- append_catch_all (iv);
- catch_all_appended = true;
+ append_cleanup (iv);
+ cleanup_appended = true;
}
if (processing_handler)
{
@@ -3297,15 +3303,15 @@
FmtAssert (eh_spec, ("Invalid eh_spec inside handler"));
if (!eh_spec->empty())
{
- if (!catch_all_appended)
- append_catch_all (iv);
+ if (!cleanup_appended)
+ append_cleanup (iv);
append_eh_filter (iv);
}
}
else if (!eh_spec_vector.empty())
{
- if (!catch_all_appended)
- append_catch_all (iv);
+ if (!cleanup_appended)
+ append_cleanup (iv);
append_eh_filter (iv);
}
if (!iv)
------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
Open64-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/open64-devel