Incoming parameters that are passed on the stack are never reported as
tracked to the GC, but `lvaIsGCTracked` (which is used to determine
whether or not to report liveness for a lclVar's stack slot) still
returned true if the corresponding lclVar was tracked. This caused
problems on x86 when dealing with incoming GC stack parameters in ESP
frames: in this case, writes to a GC stack parameter could incorrectly
change the liveness for a lclVar at the same offset from ESP as the
parameter's offset from EBP.
Fixes dotnet/coreclr#7696.
Commit migrated from https://github.com/dotnet/coreclr/commit/
a24d7e9eca0d1d8bf93f854bd9985a8e97526fab
{
VarSetOps::AddElemD(compiler, compiler->raRegVarsMask, varDsc->lvVarIndex);
}
- else if (compiler->lvaIsGCTracked(varDsc) && (!varDsc->lvIsParam || varDsc->lvIsRegArg))
+ else if (compiler->lvaIsGCTracked(varDsc))
{
VarSetOps::AddElemD(compiler, gcInfo.gcTrkStkPtrLcls, varDsc->lvVarIndex);
}
{
if (varDsc->lvTracked && (varDsc->lvType == TYP_REF || varDsc->lvType == TYP_BYREF))
{
+ // Stack parameters are always untracked w.r.t. GC reportings
+ const bool isStackParam = varDsc->lvIsParam && !varDsc->lvIsRegArg;
#ifdef _TARGET_AMD64_
- return !lvaIsFieldOfDependentlyPromotedStruct(varDsc);
+ return !isStackParam && !lvaIsFieldOfDependentlyPromotedStruct(varDsc);
#else // !_TARGET_AMD64_
- return true;
+ return !isStackParam;
#endif // !_TARGET_AMD64_
}
else