Thread overview
Segfault with std.variant
Mar 25
Mitchell
Mar 28
Mitchell
March 25

Howdy,

I've just tried out std.variant and I've noticed that I can induce a segfault by having a variant of variants. Should this work?

import std.stdio;
import std.variant;

void main()
{
  Variant variant = Variant([
    "one": Variant(1),
    "two": Variant(2),
    "three": Variant(3)
  ]);

  writefln("Segfault occurs on the next line");
  variant["four"] = Variant(4); // Segfault
  writefln("This line will not be reached");
}

For whatever reason, the variant["four"] = Variant(4) line will fail with a segfault. I'm using LDC2:

LDC - the LLVM D compiler (1.31.0):
  based on DMD v2.101.2 and LLVM 14.0.3
  built with LDC - the LLVM D compiler (1.31.0)
  Default target: x86_64-unknown-linux-gnu
  Host CPU: ivybridge
March 25
On 3/24/23 23:07, Mitchell wrote:

>    variant["four"] = Variant(4); // Segfault

Today I learned that VariantN forwards to associative array operations. Cool I guess. :)

> with a segfault. I'm using LDC2:

Same with dmd. It fails in the destructor of VariantN.

    static if (!AllowedTypes.length || anySatisfy!(hasElaborateDestructor, AllowedTypes))
    {
        ~this()
        {
            // Infer the safety of the provided types
            static if (AllowedTypes.length)
            {
                if (0)
                {
                    AllowedTypes var;
                }
            }
            (() @trusted => fptr(OpID.destruct, &store, null))();
        }
    }

That @trusted lambda call segfaults.

This looks like a bug to me. Reported:

  https://issues.dlang.org/show_bug.cgi?id=23809

Ali

March 25

On Saturday, 25 March 2023 at 07:42:28 UTC, Ali Çehreli wrote:

>

This looks like a bug to me.

Such a problem does not occur when you set all objects with the new operator.

void main()
{
  import std.variant;

  auto var = Variant([
    "one": new Variant(1), "two": new Variant(2),
    "three": new Variant(3), "four": new Variant(4),
    "five": new Variant(5)
  ]);
  auto six = new Variant(6);
  var["six"] = new Variant(6);
  assert(var.length == 6);
}

SDB@79

March 28
Great! Thank you!