unsigned impInitBlockLineInfo();
- GenTree* impCheckForNullPointer(GenTree* obj);
bool impIsThis(GenTree* obj);
bool impIsLDFTN_TOKEN(const BYTE* delegateCreateStart, const BYTE* newobjCodeAddr);
bool impIsDUP_LDVIRTFTN_TOKEN(const BYTE* delegateCreateStart, const BYTE* newobjCodeAddr);
/*****************************************************************************
*
- * Check for the special case where the object is the constant 0.
- * As we can't even fold the tree (null+fldOffs), we are left with
- * op1 and op2 both being a constant. This causes lots of problems.
- * We simply grab a temp and assign 0 to it and use it in place of the NULL.
- */
-
-inline GenTree* Compiler::impCheckForNullPointer(GenTree* obj)
-{
- /* If it is not a GC type, we will be able to fold it.
- So don't need to do anything */
-
- if (!varTypeIsGC(obj->TypeGet()))
- {
- return obj;
- }
-
- if (obj->gtOper == GT_CNS_INT)
- {
- assert(obj->gtType == TYP_REF || obj->gtType == TYP_BYREF);
-
- // We can see non-zero byrefs for RVA statics or for frozen strings.
- if (obj->AsIntCon()->gtIconVal != 0)
- {
-#ifdef DEBUG
- if (!obj->TypeIs(TYP_BYREF))
- {
- assert(obj->TypeIs(TYP_REF));
- assert(obj->IsIconHandle(GTF_ICON_STR_HDL));
- if (!doesMethodHaveFrozenString())
- {
- assert(compIsForInlining());
- assert(impInlineInfo->InlinerCompiler->doesMethodHaveFrozenString());
- }
- }
-#endif // DEBUG
- return obj;
- }
-
- unsigned tmp = lvaGrabTemp(true DEBUGARG("CheckForNullPointer"));
-
- // We don't need to spill while appending as we are only assigning
- // NULL to a freshly-grabbed temp.
-
- impAssignTempGen(tmp, obj, (unsigned)CHECK_SPILL_NONE);
-
- obj = gtNewLclvNode(tmp, obj->gtType);
- }
-
- return obj;
-}
-
-/*****************************************************************************
- *
* Check for the special case where the object is the methods original 'this' pointer.
* Note that, the original 'this' pointer is always local var 0 for non-static method,
* even if we might have created the copy of 'this' pointer in lvaArg0Var.
}
}
- op1 = impCheckForNullPointer(op1);
-
/* Mark the block as containing an index expression */
if (op1->gtOper == GT_LCL_VAR)
op2->gtType = TYP_I_IMPL;
}
- op3 = impCheckForNullPointer(op3);
-
// Mark the block as containing an index expression
if (op3->gtOper == GT_LCL_VAR)
case CORINFO_FIELD_INSTANCE_WITH_BASE:
#endif
{
- obj = impCheckForNullPointer(obj);
-
// If the object is a struct, what we really want is
// for the field to operate on the address of the struct.
if (!varTypeGCtype(obj->TypeGet()) && impIsValueType(tiObj))
case CORINFO_FIELD_INSTANCE_WITH_BASE:
#endif
{
- obj = impCheckForNullPointer(obj);
-
/* Create the data member node */
op1 = gtNewFieldRef(lclTyp, resolvedToken.hField, obj, fieldInfo.offset);
DWORD typeFlags = info.compCompHnd->getClassAttribs(resolvedToken.hClass);
fgWalkTreePost(&value, resetMorphedFlag);
#endif // DEBUG
- GenTree* const nullCheckedArr = impCheckForNullPointer(arr);
- GenTree* const arrIndexNode = gtNewIndexRef(TYP_REF, nullCheckedArr, index);
- GenTree* const arrStore = gtNewAssignNode(arrIndexNode, value);
- arrStore->gtFlags |= GTF_ASG;
+ GenTree* const arrIndexNode = gtNewIndexRef(TYP_REF, arr, index);
+ GenTree* const arrStore = gtNewAssignNode(arrIndexNode, value);
GenTree* result = fgMorphTree(arrStore);
if (argSetup != nullptr)