Author: fengzhou
Date: 2011-01-25 17:08:21 -0500 (Tue, 25 Jan 2011)
New Revision: 3469

Modified:
   trunk/MAINTAINERS
   trunk/osprey/wgen/wgen_decl.cxx
   trunk/osprey/wgen/wgen_expr.cxx
Log:
fix for bug #585(https://bugs.open64.net/show_bug.cgi?id=585). There are three 
test cases attached to the bug report. They all experience same
problem: compile time segmentation fault at wgen phase. However, each of them 
is caused by a different problem.

Code Review: Jian-Xin Lai

pr22061-2.c
===========
The test case is shown below:

int *x;
static void bar (char a[2][(*x)++]) {}

The problem is that when generating type information for bar function, (*x)++ 
needs to be expanded since `a` is a variable length array.
However, current wgen assumes that WHIRL node for current function
(`Current_Entry_Wn()`) already exists. However, this is not true at the time of 
generating function type information.

crash2.C
========
The part of code causing problems is shown below:

R1::R1( const R& a ) :
   m_( a.empty() ? get_empty().m_ : C() )

The gspin expression for the select is organized as follows:

COND_EXPR
 |-- COND
 |-- TARGET_EXPR
     |-- COMPONENT_REF (S1)
          |-- INDIRECT_REF
          |-- ...
     |-- COMPONENT_REF (S2)
          |-- TARGET_REF
          |-- ...
 |-- ...

S1 is actually a VAR_DECL expression in gspin file. It is changed to 
COMPONENT_REF when converting COND_EXPR (see wgen_expr.cxx:6056, added for bug 
15210). However, the presence of INDIRECT_REF causes target symbol being NULL 
and this caused segmentation fault in WN_Lda function.

ftp.i
=====
The following code snippet caused the problem:

struct string {
   unsigned char *source;
};
struct ftp_file_info {
   struct string name;
   struct string symlink;
   long size;
   time_t mtime;
   unsigned int local_time_zone:1;
   mode_t permissions;
};
static int ftp_process_dirlist()
{
   int ret = 0;
   while (1) {
       struct ftp_file_info ftp_info = { FTP_FILE_UNKNOWN, {"", 0}, {"", 0}, 
-1, 0, 0 };
   }
}

The compiler tries to generate initialization code for each field of 
`ftp_info`. For each field, `Advance_Field_Id` is called to advance to next 
field after generating initialization code for current field. Due to the 
presence of `struct string`, the field_id and fld is no long in sync. For 
example, after generating initialization code for ftp_info.symlink, the 
field_id is the for the last field of symlink struct (ftp_info.symlink.source) 
while fld still points to ftp_info.symlink field. This caused field_id being 
incremented incorrectly and caused segmentation fault in `FLD_get_to_field` 
function.

ALSO: update my email address in MAINTAINERS file


Modified: trunk/MAINTAINERS
===================================================================
--- trunk/MAINTAINERS   2011-01-24 21:28:33 UTC (rev 3468)
+++ trunk/MAINTAINERS   2011-01-25 22:08:21 UTC (rev 3469)
@@ -104,7 +104,7 @@
 Paul Yuan                      yingbo.com(AT)gmail.com
 Duo Zhang                      zhangduo07(AT)mails.tsinghua.edu.cn
 Min Zhao                       min.zhao(AT)hp.com
-Feng Zhou                      fengzhouzh(AT)gmail.com
+Feng Zhou                      feng.zhou(AT)hp.com
 Hucheng Zhou                   zhou.hucheng(AT)gmail.com
 Xing Zhou                      zhouxing05(AT)gmail.com
 Qing Zhu                        zqing1...@gmail.com

Modified: trunk/osprey/wgen/wgen_decl.cxx
===================================================================
--- trunk/osprey/wgen/wgen_decl.cxx     2011-01-24 21:28:33 UTC (rev 3468)
+++ trunk/osprey/wgen/wgen_decl.cxx     2011-01-25 22:08:21 UTC (rev 3469)
@@ -244,7 +244,13 @@
 static std::vector<WN*> curr_entry_wn;
 static void Push_Current_Entry_WN(WN *wn) { curr_entry_wn.push_back(wn); }
 static void Pop_Current_Entry_WN() { curr_entry_wn.pop_back(); }
-WN *Current_Entry_WN(void) { return curr_entry_wn.back(); }
+WN *Current_Entry_WN(void) {
+    if (curr_entry_wn.size()==0) {
+        return NULL;
+    } else {
+        return curr_entry_wn.back(); 
+    }
+}
 
 // Any typeinfo symbols that we have determined we should emit
 std::vector<gs_t> emit_typeinfos;
@@ -3269,23 +3275,11 @@
 
 #ifdef FE_GNU_4_2_0
   INT length = gs_constructor_length(init_list);
-#ifdef KEY
-  if (length > 0)
-    ++field_id; // compute field_id for current field
-#endif
   for (INT idx = 0;
        idx < length;
        idx++) {
 
-#ifdef KEY
-    // Bug 14422: Do the first increment outside the loop. Then advance
-    // the field_id at the tail end of the loop before moving on to next
-    // field, taking into account any fields inside current struct field.
-    // The update at the tail end is done only if there is an iteration
-    // left.
-#else
     ++field_id; // compute field_id for current field
-#endif
     gs_t element_index = gs_constructor_elts_index(init_list, idx);
 
     // if the initialization is not for the current field,
@@ -3437,22 +3431,13 @@
       }
     }
 
-#ifdef KEY
-    // Bug 14422:
-    // Count current field before moving to next field. The current field
-    // may be of struct type, in which case its fields need to be counted.
-    // We increment the field-id here instead of at the start of the loop.
-    if (idx < length-1) // only if there is an iteration left
-      field_id = Advance_Field_Id(fld, field_id);
-#endif
-    // advance ot next field
     current_offset = current_offset_base + emitted_bytes;
     fld = FLD_next(fld);
     field = next_real_field(type, field);
     while (field && gs_tree_code(field) != GS_FIELD_DECL)
       field = next_real_field(type, field);
   }
-#else
+#else // end FE_GNU_4_2_0
 #ifdef KEY
   if (gs_constructor_elts(init_list))
     ++field_id; // compute field_id for current field
@@ -3688,6 +3673,7 @@
 #ifdef KEY
     field_id = Advance_Field_Id(fld,field_id)-1;
 #endif
+
     fld = FLD_next(fld);
     field = next_real_field(type, field);
     while (field && gs_tree_code(field) != GS_FIELD_DECL)

Modified: trunk/osprey/wgen/wgen_expr.cxx
===================================================================
--- trunk/osprey/wgen/wgen_expr.cxx     2011-01-24 21:28:33 UTC (rev 3468)
+++ trunk/osprey/wgen/wgen_expr.cxx     2011-01-25 22:08:21 UTC (rev 3469)
@@ -1885,7 +1885,10 @@
        // object requires it.  In such a case, the copy constructor is always
        // defined.
         gs_t addr = gs_tree_operand(lhs, 0);
-        WN *first_formal = WN_formal(Current_Entry_WN(), 0);
+        WN *first_formal = NULL;
+        if (Current_Entry_WN() != NULL) {
+            first_formal = WN_formal(Current_Entry_WN(), 0);
+        }
         if (TY_return_in_mem(hi_ty_idx) &&
            field_id == 0 &&
            // See if it is an indirect ref of the fake first parm.
@@ -5982,7 +5985,7 @@
            }
          }
           // OSP_397, if opnd 0 of TARGET_EXPR is an COMPONENT_REF
-          else if (gs_tree_code(t) == GS_AGGR_INIT_EXPR &&
+          else if (gs_tree_code(t) == GS_AGGR_INIT_EXPR && 
                    gs_tree_code(opnd0) == GS_COMPONENT_REF) {
             WN *target_wn = WGEN_Address_Of(opnd0);
             WN *result_wn = WGEN_Expand_Expr (t, TRUE /* for return_in_mem*/, 
@@ -5990,7 +5993,52 @@
             /* We ignore the result_wn, for safety, place an assertion here */
             FmtAssert(result_wn == NULL,
                       ("result_wn should be NULL for the result is passed as 
param."));
-          }      
+          } else if (gs_tree_code(t) == GS_COMPONENT_REF &&
+                  gs_tree_code(opnd0) == GS_COMPONENT_REF &&
+                  gs_tree_code(gs_tree_operand(opnd0, 0)) == GS_INDIRECT_REF) {
+              /*
+               * match the following kind of tree 
+               * - TARGET_REF
+               * |-0 COMPONENT_REF
+               *   |- 0 INDIRECT_REF
+               *   |- 1 FIELD
+               * |-1 COMPONENT_REF
+               */
+              // generate rhs first
+                         WN *rhs_wn = WGEN_Expand_Expr (t, TRUE /* for 
return_in_mem*/,
+                                         0, 0, 0, 0, FALSE, FALSE, NULL);
+
+              gs_t obj_instance = gs_tree_operand(opnd0, 0);
+              gs_t obj_ptr = gs_tree_operand(obj_instance, 0);
+
+              gs_t member = gs_tree_operand(opnd0, 1);
+              WN_OFFSET ofst = 0;
+              UINT xtra_BE_ofst = 0;
+
+              TY_IDX obj_ty_idx = Get_TY(gs_tree_type(gs_tree_operand(obj_ptr, 
0)));
+
+              ofst = (BITSPERBYTE * 
gs_get_integer_value(gs_decl_field_offset(member)) +
+                      gs_get_integer_value(gs_decl_field_bit_offset(member)))
+                  / BITSPERBYTE;
+
+
+              WN *obj_wn = WGEN_Expand_Expr(obj_ptr, TRUE, 0, 0, 0, 0, FALSE, 
FALSE, NULL);
+
+              TY_IDX hi_ty_idx;
+              if (gs_tree_code(gs_tree_type(opnd0)) == GS_VOID_TYPE)
+                  hi_ty_idx = MTYPE_To_TY(MTYPE_I4); // dummy; for bug 10176 
Comment #4
+              else hi_ty_idx = Get_TY(gs_tree_type(opnd0));
+
+              desc_ty_idx = hi_ty_idx;
+              ty_idx = desc_ty_idx;
+
+              wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, TY_mtype(hi_ty_idx),
+                      xtra_BE_ofst,
+                      obj_ty_idx,
+                      rhs_wn, obj_wn, DECL_FIELD_ID(member));
+              WGEN_Stmt_Append(wn, Get_Srcpos());
+              break;
+                 }
          //15210
           else if (gs_tree_code(t) == GS_CALL_EXPR &&
                    gs_tree_code(opnd0) == GS_COMPONENT_REF) {


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to