From: sivarv Date: Tue, 15 Mar 2016 20:23:29 +0000 (-0700) Subject: Fix to issue #3734 X-Git-Tag: accepted/tizen/base/20180629.140029~5295^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=301bf0a08a391797edcb8f9e7fffd29f232d09cb;p=platform%2Fupstream%2Fcoreclr.git Fix to issue #3734 --- diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 16ece5f..44ec95d 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -14165,28 +14165,32 @@ void Compiler::fgMorphBlocks() fgReturnCount--; } - // Block is guaranteed to have last stmt as its jump kind is BBJ_RETURN. - // Note that it a block with jump kind BBJ_RETURN not necessarily needs to end with GT_RETURN. + // Note 1: A block is not guaranteed to have a last stmt if its jump kind is BBJ_RETURN. + // For example a method returning void could have an empty block with jump kind BBJ_RETURN. + // Such blocks do materialize as part of in-lining. + // + // Note 2: A block with jump kind BBJ_RETURN does not necessarily need to end with GT_RETURN. // It could end with a tail call or rejected tail call or monitor.exit or a GT_INTRINSIC. // For now it is safe to explicitly check whether last stmt is GT_RETURN if genReturnLocal // is BAD_VAR_NUM. // // TODO: Need to characterize the last top level stmt of a block ending with BBJ_RETURN. - noway_assert(block->bbTreeList); - GenTreePtr last = block->bbTreeList->gtPrev; - noway_assert(last != nullptr); - noway_assert(last->gtNext == nullptr); - noway_assert(last->gtOper == GT_STMT); - - GenTreePtr ret = last->gtStmt.gtStmtExpr; - noway_assert(ret != nullptr); - + GenTreePtr last = (block->bbTreeList != nullptr) ? block->bbTreeList->gtPrev : nullptr; + GenTreePtr ret = (last != nullptr) ? last->gtStmt.gtStmtExpr : nullptr; + //replace the GT_RETURN node to be a GT_ASG that stores the return value into genReturnLocal. if (genReturnLocal != BAD_VAR_NUM) { + // Method must be returning a value other than TYP_VOID. noway_assert(compMethodHasRetVal()); + // This block must be ending with a GT_RETURN + noway_assert(last != nullptr); + noway_assert(last->gtOper == GT_STMT); + noway_assert(last->gtNext == nullptr); + noway_assert(ret != nullptr); + // GT_RETURN must have non-null operand as the method is returning the value assigned to genReturnLocal noway_assert(ret->OperGet() == GT_RETURN); noway_assert(ret->gtGetOp1() != nullptr); @@ -14197,8 +14201,13 @@ void Compiler::fgMorphBlocks() //make sure that copy-prop ignores this assignment. last->gtStmt.gtStmtExpr->gtFlags |= GTF_DONT_CSE; } - else if (ret->OperGet() == GT_RETURN) + else if (ret != nullptr && ret->OperGet() == GT_RETURN) { + // This block ends with a GT_RETURN + noway_assert(last != nullptr); + noway_assert(last->gtOper == GT_STMT); + noway_assert(last->gtNext == nullptr); + // Must be a void GT_RETURN with null operand; delete it as this block branches to oneReturn block noway_assert(ret->TypeGet() == TYP_VOID); noway_assert(ret->gtGetOp1() == nullptr);