Skip to content

Edge case where unnecessary unchecked scope is generated for integer literals #709

Description

@Exanite

Context

This was discovered as I was working on #699 and my original explanation of the issue can be found here: #699 (comment).

Generator outputs

Currently (assuming #699 has been merged), SDL_size_add_check_overflow generates with an unnecessary unchecked scope.

// C
bool SDL_size_add_check_overflow(size_t a, size_t b, size_t *ret)
{
    if (b > (18446744073709551615UL) - a) {
        return false;
    }
    *ret = a + b;
    return true;
}
// C# - Current
public static bool SDL_size_add_check_overflow([NativeTypeName(""size_t"")] nuint a, [NativeTypeName(""size_t"")] nuint b, [NativeTypeName(""size_t *"")] nuint* ret)
{
    if (b > unchecked(18446744073709551615U) - a)
    {
        return (0) != 0;
    }

    *ret = a + b;
    return (1) != 0;
}
// C# - Ideal
public static bool SDL_size_add_check_overflow([NativeTypeName(""size_t"")] nuint a, [NativeTypeName(""size_t"")] nuint b, [NativeTypeName(""size_t *"")] nuint* ret)
{
    if (b > (18446744073709551615U) - a)
    {
        return (0) != 0;
    }

    *ret = a + b;
    return (1) != 0;
}

As decided in the PR, the generator currently outputs unchecked(18446744073709551615U), but ideally, it outputs (18446744073709551615U). The underlying issue is that the generator does not assign the correct targetTypeName to the integer literal.

The test case is already part of the codebase as the CLongDefinesRegressionTestUnix test case in the CTest.cs file (again assuming the linked PR has been merged).

My understanding of the issue

My understanding of the issue is that this is an edge case with how ClangSharpPInvokeGenerator assigns the targetTypeName for the integer literal (18446744073709551615U). The integer literal takes the type of the binary expression it is part of and the binary expression itself takes the type of the parameter a. This means that whether the integer literal has an unchecked scope depends on the type of a.

This can be verified by changing the type of a in the C code so that it no longer outputs as nuint in the C# code.

I also speculate on a potential fix in my original comment in the PR: #699 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions