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