summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/System.Private.CoreLib/Resources/Strings.resx2
-rw-r--r--src/System.Private.CoreLib/src/System/Activator.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/RtType.cs9
-rw-r--r--src/System.Private.CoreLib/src/System/RuntimeHandles.cs2
-rw-r--r--src/vm/reflectioninvocation.cpp24
-rw-r--r--src/vm/runtimehandles.h5
6 files changed, 29 insertions, 15 deletions
diff --git a/src/System.Private.CoreLib/Resources/Strings.resx b/src/System.Private.CoreLib/Resources/Strings.resx
index de7eb5ba00..fe7ea71be3 100644
--- a/src/System.Private.CoreLib/Resources/Strings.resx
+++ b/src/System.Private.CoreLib/Resources/Strings.resx
@@ -584,7 +584,7 @@
<value>Must specify binding flags describing the invoke operation required (BindingFlags.InvokeMethod CreateInstance GetField SetField GetProperty SetProperty).</value>
</data>
<data name="Arg_NoDefCTor" xml:space="preserve">
- <value>No parameterless constructor defined for this object.</value>
+ <value>No parameterless constructor defined for type '{0}'.</value>
</data>
<data name="Arg_NoITypeInfo" xml:space="preserve">
<value>Specified TypeInfo was invalid because it did not support the ITypeInfo interface.</value>
diff --git a/src/System.Private.CoreLib/src/System/Activator.cs b/src/System.Private.CoreLib/src/System/Activator.cs
index c2197d4c3b..88c7e60a11 100644
--- a/src/System.Private.CoreLib/src/System/Activator.cs
+++ b/src/System.Private.CoreLib/src/System/Activator.cs
@@ -221,7 +221,7 @@ namespace System
// This is a workaround to maintain compatibility with V2. Without this we would throw a NotSupportedException for void[].
// Array, Ref, and Pointer types don't have default constructors.
if (rt.HasElementType)
- throw new MissingMethodException(SR.Arg_NoDefCTor);
+ throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, rt));
// Skip the CreateInstanceCheckThis call to avoid perf cost and to maintain compatibility with V2 (throwing the same exceptions).
return (T)rt.CreateInstanceDefaultCtor(publicOnly: true, skipCheckThis: true, fillCache: true, wrapExceptions: true);
diff --git a/src/System.Private.CoreLib/src/System/RtType.cs b/src/System.Private.CoreLib/src/System/RtType.cs
index 3bab50597e..743e2291e5 100644
--- a/src/System.Private.CoreLib/src/System/RtType.cs
+++ b/src/System.Private.CoreLib/src/System/RtType.cs
@@ -4768,11 +4768,16 @@ namespace System
{
RuntimeMethodHandleInternal runtime_ctor = default;
bool bCanBeCached = false;
+ bool bHasNoDefaultCtor = false;
if (!skipCheckThis)
CreateInstanceCheckThis();
- object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, wrapExceptions, ref bCanBeCached, ref runtime_ctor);
+ object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, wrapExceptions, ref bCanBeCached, ref runtime_ctor, ref bHasNoDefaultCtor);
+ if (bHasNoDefaultCtor)
+ {
+ throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, this));
+ }
if (bCanBeCached && fillCache)
{
@@ -4809,7 +4814,7 @@ namespace System
if (ace.m_ctor != null &&
(ace.m_ctorAttributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
{
- throw new MissingMethodException(SR.Arg_NoDefCTor);
+ throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, this));
}
}
diff --git a/src/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/System.Private.CoreLib/src/System/RuntimeHandles.cs
index 03d9233f59..030b9abaf8 100644
--- a/src/System.Private.CoreLib/src/System/RuntimeHandles.cs
+++ b/src/System.Private.CoreLib/src/System/RuntimeHandles.cs
@@ -219,7 +219,7 @@ namespace System
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern object CreateInstance(RuntimeType type, bool publicOnly, bool wrapExceptions, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor);
+ internal static extern object CreateInstance(RuntimeType type, bool publicOnly, bool wrapExceptions, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor, ref bool hasNoDefaultCtor);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern object CreateCaInstance(RuntimeType type, IRuntimeMethodInfo ctor);
diff --git a/src/vm/reflectioninvocation.cpp b/src/vm/reflectioninvocation.cpp
index d9ed5fb98b..dd112ebf0a 100644
--- a/src/vm/reflectioninvocation.cpp
+++ b/src/vm/reflectioninvocation.cpp
@@ -372,18 +372,21 @@ FCIMPL1(Object*, RuntimeTypeHandle::Allocate, ReflectClassBaseObject* pTypeUNSAF
}//Allocate
FCIMPLEND
-FCIMPL5(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refThisUNSAFE,
+FCIMPL6(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refThisUNSAFE,
CLR_BOOL publicOnly,
CLR_BOOL wrapExceptions,
CLR_BOOL* pbCanBeCached,
- MethodDesc** pConstructor) {
+ MethodDesc** pConstructor,
+ CLR_BOOL* pbHasNoDefaultCtor) {
CONTRACTL {
FCALL_CHECK;
PRECONDITION(CheckPointer(refThisUNSAFE));
PRECONDITION(CheckPointer(pbCanBeCached));
PRECONDITION(CheckPointer(pConstructor));
+ PRECONDITION(CheckPointer(pbHasNoDefaultCtor));
PRECONDITION(*pbCanBeCached == false);
PRECONDITION(*pConstructor == NULL);
+ PRECONDITION(*pbHasNoDefaultCtor == false);
}
CONTRACTL_END;
@@ -406,8 +409,10 @@ FCIMPL5(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT
MethodTable* pVMT;
// Get the type information associated with refThis
- if (thisTH.IsNull() || thisTH.IsTypeDesc())
- COMPlusThrow(kMissingMethodException,W("Arg_NoDefCTor"));
+ if (thisTH.IsNull() || thisTH.IsTypeDesc()) {
+ *pbHasNoDefaultCtor = true;
+ goto DoneCreateInstance;
+ }
pVMT = thisTH.AsMethodTable();
@@ -458,7 +463,8 @@ FCIMPL5(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT
// if this is a Value class we can simply allocate one and return it
if (!pVMT->IsValueType()) {
- COMPlusThrow(kMissingMethodException,W("Arg_NoDefCTor"));
+ *pbHasNoDefaultCtor = true;
+ goto DoneCreateInstance;
}
// Handle the nullable<T> special case
@@ -480,8 +486,10 @@ FCIMPL5(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT
// Validate the method can be called by this caller
DWORD attr = pMeth->GetAttrs();
- if (!IsMdPublic(attr) && publicOnly)
- COMPlusThrow(kMissingMethodException, W("Arg_NoDefCTor"));
+ if (!IsMdPublic(attr) && publicOnly) {
+ *pbHasNoDefaultCtor = true;
+ goto DoneCreateInstance;
+ }
// We've got the class, lets allocate it and call the constructor
OBJECTREF o;
@@ -515,7 +523,7 @@ FCIMPL5(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT
}
}
}
-
+DoneCreateInstance:
HELPER_METHOD_FRAME_END();
return OBJECTREFToObject(rv);
}
diff --git a/src/vm/runtimehandles.h b/src/vm/runtimehandles.h
index dc379d827e..e1f265d36e 100644
--- a/src/vm/runtimehandles.h
+++ b/src/vm/runtimehandles.h
@@ -126,11 +126,12 @@ public:
// Static method on RuntimeTypeHandle
static FCDECL1(Object*, Allocate, ReflectClassBaseObject *refType) ; //A.CI work
- static FCDECL5(Object*, CreateInstance, ReflectClassBaseObject* refThisUNSAFE,
+ static FCDECL6(Object*, CreateInstance, ReflectClassBaseObject* refThisUNSAFE,
CLR_BOOL publicOnly,
CLR_BOOL wrapExceptions,
CLR_BOOL *pbCanBeCached,
- MethodDesc** pConstructor);
+ MethodDesc** pConstructor,
+ CLR_BOOL *pbHasNoDefaultCtor);
static FCDECL2(Object*, CreateCaInstance, ReflectClassBaseObject* refCaType, ReflectMethodObject* pCtorUNSAFE);