summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLubomir Litchev <LLITCHEV@users.noreply.github.com>2015-10-26 10:15:18 -0700
committerLubomir Litchev <LLITCHEV@users.noreply.github.com>2015-10-26 10:15:18 -0700
commite487749d77066732aacd4a57deb60edbe97883f7 (patch)
treeb8fe376ccd37ae23cf71d865ba8026977aeb6fa4 /src
parent83a78f96b95fd67c7d89516256ccb9cb9c909452 (diff)
parent1fd0ea45a8b469c070b3f95472ec3149faa22815 (diff)
downloadcoreclr-e487749d77066732aacd4a57deb60edbe97883f7.tar.gz
coreclr-e487749d77066732aacd4a57deb60edbe97883f7.tar.bz2
coreclr-e487749d77066732aacd4a57deb60edbe97883f7.zip
Merge pull request #1862 from LLITCHEV/Issue1831
Fixed the bug described in GH issue 1831.
Diffstat (limited to 'src')
-rw-r--r--src/jit/importer.cpp30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index 0ee654c837..e0be19ecfd 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -12572,8 +12572,10 @@ FIELD_DONE:
// Unbox nullable helper returns a TYP_STRUCT.
// We need to spill it to a temp so than we can take the address of it.
// We need the temp so we can pass its address to the unbox_nullable jit helper function.
- // This is needed for 2 register returned nullables.
- // The one register ones are normalized. For the bigger than 16 bytes ones there is retbuf already passed in rdi.
+ // This is needed for nullables returned in 2 registers.
+ // The ones returned in a single register are normalized.
+ // For the bigger than 16 bytes nullables there is retbuf already passed in
+ // rdi/rsi (depending whether there is a "this").
unsigned tmp = lvaGrabTemp(true DEBUGARG("UNBOXing a register returnable nullable"));
lvaTable[tmp].lvDontPromote = true;
@@ -12585,14 +12587,34 @@ FIELD_DONE:
op2 = gtNewLclvNode(tmp, TYP_STRUCT);
op2 = gtNewOperNode(GT_ADDR, TYP_BYREF, op2);
- op1 = gtNewOperNode(GT_COMMA, TYP_STRUCT, op1, op2);
+ op1 = gtNewOperNode(GT_COMMA, TYP_BYREF, op1, op2);
+
+ // In this case the return value of the unbox helper is TYP_BYREF.
+ // Make sure the right type is placed on the operand type stack.
+ impPushOnStack(op1, tiRetVal);
+
+ // Load the struct.
+ oper = GT_LDOBJ;
+
+ assert(op1->gtType == TYP_BYREF);
+ assert(!tiVerificationNeeded || tiRetVal.IsByRef());
+
+ goto LDOBJ;
+ }
+ else
+ {
+ // If non register passable struct we have it materialized in the RetBuf.
+ assert(op1->gtType == TYP_STRUCT);
+ tiRetVal = verMakeTypeInfo(resolvedToken.hClass);
+ assert(tiRetVal.IsValueClass());
}
}
-#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#else // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
assert(op1->gtType == TYP_STRUCT);
tiRetVal = verMakeTypeInfo(resolvedToken.hClass);
assert(tiRetVal.IsValueClass());
+#endif // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
}
impPushOnStack(op1, tiRetVal);