Fix generation of long-typed defines when on Linux#699
Conversation
This is my initial guess for what the output should look like.
|
There is also a similar case with Also from OpenCL: #if INTPTR_MAX == INT32_MAX
#define CL_ICD2_TAG_KHR ((intptr_t)0x434C3331)
#else
#define CL_ICD2_TAG_KHR ((intptr_t)0x4F50454E434C3331)
#endifThis generates as the following on both Windows and Linux: [NativeTypeName("#define CL_ICD2_TAG_KHR ((intptr_t)0x4F50454E434C3331)")]
public const nint CL_ICD2_TAG_KHR = unchecked((nint)(0x4F50454E434C3331));In this case, the only change needed to make this compile would be to replace |
… other observations
Will keep investigating the conditions a bit more since I'm not quite convinced this is optimal.
These apparently error during compile time, but not edit time. I.e., there's no red underline displayed in the editor, but will fail with "The expression being assigned to 'MyMacro1' must be constant".
Looks like the ranges are consistent, but I didn't realize since the existing UncheckedConversionMacroTest cases were wrong (see previous commit).
typeNameBacking eventually calls into GetTypeName, which can return either the keyword or the underlying type name depending on the generator configuration, so I believe this change is correct.
| public static partial class Methods | ||
| {{ | ||
| [NativeTypeName(""#define MyMacro1 (long)0x80000000L"")] | ||
| public const IntPtr MyMacro1 = unchecked((nint)(0x80000000)); |
There was a problem hiding this comment.
Old expected output doesn't actually compile and fails with The expression being assigned to 'MyMacro1' must be constant.
This is easy to miss since the error does not show until you actually compile.
| case CXType_ULongLong: | ||
| { | ||
| if (typeNameBacking.Equals("nuint", StringComparison.Ordinal)) | ||
| if (typeNameBacking is "nuint" or "UIntPtr") |
There was a problem hiding this comment.
This change and the 3 other related changes are inconsistencies I noticed while working on the main issue. These are otherwise not related to the main issue addressed by this PR.
typeNameBacking eventually calls into GetTypeName, which can return either the keyword or the underlying type name depending on the generator configuration, so I believe this change is correct.
…nge checks Didn't realize that IsUnchecked were effectively two different methods with the same name rather than just a simple overload.
|
Going to mark ready for review for some feedback, but not ready for merge. The new CLongDefinesRegressionTestUnix test case represents a fairly harmless, but non-ideal case that I'm not quite sure how to handle. The difference is the extra/redundant I'll keep investigating on my end, but my current ideas go in a few directions:
The diffs are otherwise exactly as I want them to be. |
Summary
For context, C
longis output as C#ninton Linux.This causes an issue where a 64-bit
ulongvalue can be used as the initializer for aconstfield of typenint, leading to 2 errors:longtonint, causing a compile error.nintuntil run time, this errors withConstant initializer must be compile-time constantafter fixing the first error. This is specified here: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-9.0/native-integers.mdThis PR fixes the issue by updating the generator to output the expected test output below, along with some additional test cases.
Current test outputs (matching main branch)
This is the current output of the new
CLongDefinesTestUnixtest case on Linux when ran against the main branch.The new
CLongDefinesTestWindowstest case already passes and is there to ensure that no unintended changes occur to the Windows behavior.Expected test outputs
The expected test outputs are my proposal for roughly what the expected bindings output should look like.
Notably, we need to add a type cast and change the field to be a
static readonlyfield instead of aconstfield.Remaining Tasks
I'll handle these tasks before undrafting.
SDL_size_add_check_overflowand fix unnecessaryuncheckedstatement