From patchwork Mon Feb 21 22:41:51 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [trans-mem] PR47746: handle OBJ_TYPE_REF correctly Date: Mon, 21 Feb 2011 12:41:51 -0000 From: Aldy Hernandez X-Patchwork-Id: 83884 Message-Id: <4D62EA2F.7090306@redhat.com> To: Richard Henderson , gcc-patches , Patrick MARLIER While building the call to TM_GETTMCLONE, we discard OBJ_TYPE_REF's if we can't fold them: /* Discard OBJ_TYPE_REF, since we weren't able to fold it. */ if (TREE_CODE (old_fn) == OBJ_TYPE_REF) old_fn = OBJ_TYPE_REF_EXPR (old_fn); However, this discard can get rid of an implicit conversion. In the attached testcase, the inner type of the OBJ_TYPE_REF_EXPR is signed, but the type of the OBJ_TYPE_REF_EXPR is unsigned. This causes an ICE while verifying the gimple call. I have fixed this by adding an appropriate conversion after the GETTMCLONE call. I can make sure the conversion only happens for the OBJ_TYPE_REF, but I was lazy. I don't think it'll hurt. OK for branch? PR 47746 * trans-mem.c (ipa_tm_insert_gettmclone_call): Verify type compatibility in call. Index: testsuite/g++.dg/tm/pr47746.C =================================================================== --- testsuite/g++.dg/tm/pr47746.C (revision 0) +++ testsuite/g++.dg/tm/pr47746.C (revision 0) @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options "-fgnu-tm" } + +class InputStream +{ + public: + virtual unsigned int readUint32 () = 0; +}; + +class Building +{ + public: + __attribute__((transaction_safe)) Building (InputStream *stream); + __attribute__((transaction_safe)) void freeGradients (); + void load (InputStream *stream); +}; + +Building::Building (InputStream *stream) +{ + load(stream); +} + +void Building::load (InputStream *stream) +{ + int j = (int)stream->readUint32 (); + freeGradients (); +} Index: trans-mem.c =================================================================== --- trans-mem.c (revision 170360) +++ trans-mem.c (working copy) @@ -4274,6 +4274,27 @@ ipa_tm_insert_gettmclone_call (struct cg gimple_call_set_noinline_p (stmt); gimple_call_set_fn (stmt, callfn); + + /* Discard OBJ_TYPE_REF above, may produce incompatible LHS and RHS + for a call statement. Fix it. */ + { + tree lhs = gimple_call_lhs (stmt); + tree rettype = TREE_TYPE (TREE_TYPE (TREE_TYPE (callfn))); + if (lhs + && !useless_type_conversion_p (TREE_TYPE (lhs), rettype)) + { + tree temp; + + temp = make_rename_temp (rettype, 0); + gimple_call_set_lhs (stmt, temp); + + g2 = gimple_build_assign (lhs, + fold_build1 (VIEW_CONVERT_EXPR, + TREE_TYPE (lhs), temp)); + gsi_insert_after (gsi, g2, GSI_SAME_STMT); + } + } + update_stmt (stmt); return true;