Skip to content

Invalid C++ code generation when returning var T #10219

@BigEpsilon

Description

@BigEpsilon

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

  1. 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;
}
  1. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions