Fix FakePromote assert (#17724)
authorJan Vorlicek <janvorli@microsoft.com>
Sun, 22 Apr 2018 01:53:08 +0000 (18:53 -0700)
committerGitHub <noreply@github.com>
Sun, 22 Apr 2018 01:53:08 +0000 (18:53 -0700)
This assert was firing when there was a struct with explicit layout and
two byref fields overlapping each other. The assert was checking that
the respective location on the stack was not reported yet.
To fix that, I have changed the assert to fire only if the already
reported kind of reference was different from the current one. That
enables overlapping of two byref fields or two ref fields, but not a
byref and ref fields.

src/vm/compile.cpp

index 28283b6..de9363c 100644 (file)
@@ -924,8 +924,11 @@ void FakePromote(PTR_PTR_Object ppObj, ScanContext *pSC, uint32_t dwFlags)
         MODE_ANY;
     } CONTRACTL_END;
 
-    _ASSERTE(*ppObj == NULL);
-    *(CORCOMPILE_GCREFMAP_TOKENS *)ppObj = (dwFlags & GC_CALL_INTERIOR) ? GCREFMAP_INTERIOR : GCREFMAP_REF;
+    CORCOMPILE_GCREFMAP_TOKENS newToken = (dwFlags & GC_CALL_INTERIOR) ? GCREFMAP_INTERIOR : GCREFMAP_REF;
+
+    _ASSERTE((*ppObj == NULL) || (*(CORCOMPILE_GCREFMAP_TOKENS *)ppObj == newToken));
+
+    *(CORCOMPILE_GCREFMAP_TOKENS *)ppObj = newToken;
 }
 
 //=================================================================================