Actual behavior
Methods generated by CsWin32 that use Unsafe.NullRef throw a NRE when used regardless of parameters
Expected behavior
Methods generated by CsWin32 that use Unsafe.NullRef should not throw a NRE
Repro steps
NativeMethods.txt content:
-
NativeMethods.json content (if present): N/A
-
Any of your own code that should be shared?
Bear in mind this type of bug is a bit more nuanced.
CsWin32 generates the following:
winmdroot.Foundation.BOOL __result = PInvoke.MiniDumpWriteDump(hProcessLocal, ProcessId, hFileLocal, DumpType, ExceptionParam.HasValue ? &ExceptionParamLocal : null, UserStreamParam.HasValue ? &UserStreamParamLocal : null, CallbackParam.HasValue ? CallbackParamLocal : Unsafe.NullRef<winmdroot.System.Diagnostics.Debug.MINIDUMP_CALLBACK_INFORMATION >());
Broken down to more readable terms:
var __result = PInvoke.MiniDumpWriteDump(hProcessLocal, ProcessId, hFileLocal, DumpType, ExceptionParam.HasValue ? &ExceptionParamLocal : null, UserStreamParam.HasValue ? &UserStreamParamLocal : null,
CallbackParam.HasValue
? CallbackParamLocal
: Unsafe.NullRef<Windows.Win32.System.Diagnostics.Debug.MINIDUMP_CALLBACK_INFORMATION >());
tl;dr:
int* nul = (int*)0;
int example = 0;
int s = condition ? example : *nul;
SomeMethod(&s);
One variable is ref while the other isn't so C# lowers the modifiers till common ground is achieved.
ref + non-ref = non-ref
fix: ref + ref = ref
The issue is that CallbackParamLocal is not a ref variable. C# tries to find the most common type to send into the method that both Unsafe.NullRef and CallbackParamLocal share, so C# drops the ref attribute which causes C# to "dereference" the Unsafe.NullRef, causing an exception.
A SharpLab PoC can be found here
string str = (flag ? text : Unsafe.NullRef<string>());
the example is "dereferenced" there.
A proposed fix for this would be something like:
ref var CallbackParamReference = ref CallbackParam.HasValue
? ref CallbackParamLocal
: ref Unsafe.NullRef<Windows.Win32.System.Diagnostics.Debug.MINIDUMP_CALLBACK_INFORMATION>();
var __result = PInvoke.MiniDumpWriteDump(hProcessLocal, ProcessId, hFileLocal, DumpType, ExceptionParam.HasValue ? &ExceptionParamLocal : null, UserStreamParam.HasValue ? &UserStreamParamLocal : null, CallbackParamReference);
Context
- CsWin32 version: 0.3.183
- Win32Metadata version (if explicitly set by project): N/A
- Target Framework: net9.0-windows
LangVersion preview
Actual behavior
Methods generated by CsWin32 that use Unsafe.NullRef throw a NRE when used regardless of parameters
Expected behavior
Methods generated by CsWin32 that use Unsafe.NullRef should not throw a NRE
Repro steps
NativeMethods.txtcontent:NativeMethods.jsoncontent (if present): N/AAny of your own code that should be shared?
Bear in mind this type of bug is a bit more nuanced.
CsWin32 generates the following:
Broken down to more readable terms:
tl;dr:
One variable is ref while the other isn't so C# lowers the modifiers till common ground is achieved.
ref + non-ref = non-ref
fix: ref + ref = ref
The issue is that
CallbackParamLocalis not a ref variable. C# tries to find the most common type to send into the method that both Unsafe.NullRef andCallbackParamLocalshare, so C# drops the ref attribute which causes C# to "dereference" the Unsafe.NullRef, causing an exception.A SharpLab PoC can be found here
the example is "dereferenced" there.
A proposed fix for this would be something like:
Context
LangVersionpreview