-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Closed
Labels
Description
For the following example, the code that is generated is wrong and induce a segmentation fault.
Example
type
Vector* {.importcpp: "std::vector", header: "vector".}[T] = object
proc initVector*[T](n: csize): Vector[T]
{.importcpp: "std::vector<'*0>(@)", header: "vector".}
proc unsafeIndex[T](this: var Vector[T], i: csize): var T
{.importcpp: "#[#]", header: "vector".}
proc `[]`*[T](this: var Vector[T], i: Natural): var T {.inline, noinit.} =
when compileOption("boundChecks"):
# this.checkIndex i
discard
result = this.unsafeIndex(i)
var v1 = initVector[int](10)
echo v1[0] # <-- SIGSEGV: Illegal storage access. (Attempt to read from nil?)The error comes from the following generated lines:
static N_INLINE(NI*, X5BX5D__9bJ9bA39bRmdl9bxuHGDHoW1tQplay)(TY_DImjm4JODOV5hEJosD0PGw& this_0, NI i) {
NI* result;
nimfr_("[]", "play.nim");
nimln_(16, "play.nim");
result = this_0[((size_t) (i))]; // <-- should be: result = &this_0[((size_t)(i))];
popFrame();
return result;
}
Current Output
Traceback (most recent call last)
play.nim(17) play
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Expected Output
0
Workarounds
- using this strange syntax fixes the bug:
proc `[]`*[T](this: var Vector[T], i: Natural): var T {.inline, noinit.} =
when compileOption("boundChecks"):
# this.checkIndex i
discard
# This strange syntax is to avoid a bug in the Nim c++ code generator
result = (addr this.unsafeIndex(i))[]Here is the code generated:
static N_INLINE(NI*, X5BX5D__9bJ9bA39bRmdl9bxuHGDHoW1tQplay)(TY_DImjm4JODOV5hEJosD0PGw& this_0, NI i) {
NI* result;
nimfr_("[]", "play.nim");
nimln_(25, "play.nim");
result = (&this_0[((size_t) (i))]); // <-- this is good
popFrame();
return result;
}
- use a template instead of a proc
Additional Information
nim --version
Nim Compiler Version 0.19.9 [Linux: amd64]
Compiled at 2019-01-03
Copyright (c) 2006-2018 by Andreas Rumpf
active boot switches: -d:release