[Issue 18784] New: Segfault due to dmd codegen interfacing with C++

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri Apr 20 10:24:57 UTC 2018


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

          Issue ID: 18784
           Summary: Segfault due to dmd codegen interfacing with C++
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: blocker
          Priority: P1
         Component: dmd
          Assignee: nobody at puremagic.com
          Reporter: atila.neves at gmail.com

The following two files when compiled and linked result in a segfault when
using dmd but not ldc2:

d.d:

    extern(C++) {
        struct Struct {
            pragma(mangle, "_ZN6StructC1Ei") this(int);
            pragma(mangle, "_ZN6StructC1EOS_") this(Struct*);

            this(Struct other) {
                this(&other);
            }
        }
    }

    void main() {
        auto s = Struct(Struct(7));
    }


cpp.cpp:

    #include <stdio.h>

    struct Struct {
        Struct(int);
        Struct(Struct&&);
    };


    Struct::Struct(int) {
        printf("Oops\n");
    }

    Struct::Struct(Struct&&) { }


To reproduce:

clang++ -g -c cpp.cpp
dmd -g d.d cpp.o -L-lstdc++   # ldc2 works fine
./d


Preliminary analysis:

Removing the printf from the C++ constructor prevents the segfault. In fact, it
seems that the return value of printf is used to deference a pointer. Without
the printf, rax has the value it had before and everything works.

The bug only manifests if a temporary is passed directly to the by-value D
constructor. Changing `auto s = Struct(Struct(7))` to:

auto tmp = Struct(7);
auto s = Struct(tmp);

Makes the bug disappear.

Using ldc2 works, suggesting that the issue is due to dmd's codegen, especially
given what happens to rax as stated above.

This issue is preventing "just works" C++ integration.

--


More information about the Digitalmars-d-bugs mailing list