Thread overview
Segfault with std.variant
Mar 25, 2023
Mitchell
Mar 25, 2023
Ali Çehreli
Mar 25, 2023
Salih Dincer
Mar 28, 2023
Mitchell
March 25, 2023

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, 2023
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, 2023

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, 2023
Great! Thank you!