Nim icon indicating copy to clipboard operation
Nim copied to clipboard

fixes https://github.com/nim-lang/Nim/issues/20024

Open geekrelief opened this issue 2 years ago • 6 comments

fixes https://github.com/nim-lang/Nim/issues/20024

Added flags for enum fields and enum type when they are unsigned so their typedef will be unsigned. This fixes the range check issue when using a converter for uint32 to enum types.

type Foo = enum
  A = 0u32
  B = 0x8000_0000u32

type Bar = enum
  C = A
  D = B

converter toFoo(a: uint32): Foo = Foo(a)
converter toBar(a: uint32): Bar = Bar(a)

# These would error with a RangeDefect without the patch.
var g:Foo = 0u32
var h:Bar = 0x8000_0000u32

geekrelief avatar Jul 16 '22 06:07 geekrelief

I'm still working on this. Looks like there's still an issue with ccgexprs.nim genRangeCast where the boundaryCast is incorrect if the enum type is imported and is unsigned.

For example in the generated cpp EClassFlags has unsigned values, but aX60gensym14_ is cast to NI64:

if ((NI64)(aX60gensym14_) < ((EClassFlags) 0) || (NI64)(aX60gensym14_) > ((EClassFlags) IL64(2147483648))){ raiseRangeErrorI(aX60gensym14_, ((EClassFlags) 0), ((EClassFlags) IL64(2147483648))); }	result = ((EClassFlags) (aX60gensym14_));

geekrelief avatar Jul 16 '22 17:07 geekrelief

~~I tested this in my code base, and it looks like things are working now.~~ I still need to handle this case:

type Foo = enum
  A = 0u32
  B = 0x8000_0000u32

type Bar = enum
  C = 0
  D = (B, "Actually D")

converter toFoo(a: uint32): Foo = Foo(a)
converter toBar(a: uint32): Bar = Bar(a)

var g:Foo = 0u32
var h:Bar = 0x8000_0000u32 #<- Error: unhandled exception: value out of range: 2147483648 notin 0 .. -2147483648 [RangeDefect]

geekrelief avatar Jul 16 '22 21:07 geekrelief

This works now.

type Foo = enum
  A = 0u32
  B = 0x8000_0000u32

type Bar = enum
  C = A

type Baz = enum
  D = (B, "Actually D")

converter toFoo(a: uint32): Foo = Foo(a)
converter fromFoo(a: Foo): uint32 = uint32(a)
converter toBar(a: uint32): Bar = Bar(a)
converter toBaz(a: uint32): Baz = Baz(a)

var g:Foo = 0u32 or B
var h:Bar = 0u32 and A
var i:Baz = 0x8000_0000u32

doAssert g == B
doAssert h == C
doAssert i == D

echo g
echo h
echo i

geekrelief avatar Jul 17 '22 03:07 geekrelief

I don't know why the tests are failing here https://github.com/nim-lang/Nim/runs/7472356913?check_suite_focus=true#step:10:1406 It was working before. I cloned pixie and tests pass locally.

geekrelief avatar Jul 22 '22 17:07 geekrelief

Hi, @geekrelief thanks for your efforts on this PR!

A good pracrice to put fixes xxx on the header of the issue so that the linked issue is automatically closed. I have already edited the header.

ringabout avatar Aug 03 '22 14:08 ringabout

@ringabout Thanks for the info and edit! Do you know if the patch needs further edits before merging? Update: I just found the re-request review button!

geekrelief avatar Aug 03 '22 19:08 geekrelief