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
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to