Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Signed Enums #2138

Open
1 task
crackedmind opened this issue Feb 24, 2025 · 1 comment
Open
1 task

[Bug] Signed Enums #2138

crackedmind opened this issue Feb 24, 2025 · 1 comment
Labels
bug Something isn't working

Comments

@crackedmind
Copy link

Operating System

Windows

What's the issue you encountered?

Cant create signed enums.

How can the issue be reproduced?

enum Test : s8 {
    None = -1,
    Opt0 = 0,
    Opt1 = 1,
};

struct TestContainer {
    Test t;
    if (t != Test::None) {
        u32 data;
    }
};

TestContainer container @ 0x00;

input:
FF FE 00 00 00
output:

t = Test::???
data = 254

expected output:
t = Test::None

ImHex Version

1.37.1

ImHex Build Type

  • Nightly or built from sources

Installation type

portable

Additional context?

No response

@crackedmind crackedmind added the bug Something isn't working label Feb 24, 2025
@paxcut
Copy link
Contributor

paxcut commented Feb 24, 2025

I looked at this issue and it seems that even if you specify that the enum is 8 bit values, internally they are always 128 bits for the sake of simplifying the code. When you write None = -1, the pattern language interprets it as None = 0xFFFFFFFFFFFFFFFF. To being able to match 0xFF the PL would need to check the underlying type to parse the statement to mean None=0x00000000000000FF but that is not -1 in 128 bit representation so I can see why it doesn't do that. What it should try to do is to assign the value the the underlying type would have to be in order to satisfy the assignment and then convert that to a 128 bit integer, literally None = u8(-1),.
That can be inserted in the code to test if it would fix the issue

enum Test : s8 {
    None = u8(-1),
    Opt0 = 0,
    Opt1 = 1,
};

struct TestContainer {
    Test t;
    if (t != Test::None) {
        u32 data;
    }
};

TestContainer container @ 0x00;

which will produce the desired output t = Test::None. So when PL parses a statement like:

enum Test : s8 {
    None = -1,
    Opt0 = 0,
    Opt1 = 1,
};

it should first auto convert it to

enum Test : s8 {
    None = u8(-1),
    Opt0 =u8( 0),
    Opt1 = u8(1),
};

internally which will result in the following pattern:

enum Test : s8 {
    None = u128(u8(-1)),
    Opt0 = u128(u8(0)),
    Opt1 = u128(u8(1)),
};

whereas now it produces

enum Test : s8 {
    None = u128(-1),
    Opt0 = u128(0),
    Opt1 = u128(1),
};

which only works for positive numbers. I don't think this will be hard to code and I don't think it will have unforeseen effects but I am busy with other projects so this would have to wait a bit and if nobody picks it up in the mean time I'll tackle it in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants