[Issue 19496] New: Wrong D and C++ ABI caused by scope qualifier in other method

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Dec 16 17:15:24 UTC 2018


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

          Issue ID: 19496
           Summary: Wrong D and C++ ABI caused by scope qualifier in other
                    method
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: major
          Priority: P1
         Component: dmd
          Assignee: nobody at puremagic.com
          Reporter: ilyayaroshenko at gmail.com

t1.d:

struct S
{
    void* _payload;
    ~this();
    typeof(this) merge() { return this; }
    bool foo(ref typeof(this) rhs);
}


t2.d:

struct S
{
    void* _payload;
    ~this();
    typeof(this) merge() { return this; }
    bool foo(scope ref typeof(this) rhs);
}


As you can see the difference between this two tests is that t2.S.foo's
argument has scope qualifier.

The issue is that t1.S.merge and t2.S.merge have different ABI. Fantastic
issue, ha!

The correct ABI is in t1. The same ABI is in C++ for objects with destructors.
Note, that ABI depends on if destructor presents, both in D and C++.

The issue is represented both in DMD and LDC, both for extern(D) and
extern(C++).

LLVM output (DMD's assembler is less informative):



t.ll.S.merge:
// ABI signature returns void (as for objects with destructors)

define void @_D22t11S5mergeMFZSQBkQp(%t1.S* noalias nocapture sret align 8
%.sret_arg, %t1.S* nocapture nonnull readonly %.this_arg) local_unnamed_addr #1
comdat {

  %1 = bitcast %t1.S* %.this_arg to i64* ; [#uses = 1]
  %2 = bitcast %t1.S* %.sret_arg to i64* ; [#uses = 1]
  %3 = load i64, i64* %1, align 1                 ; [#uses = 1]
  store i64 %3, i64* %2, align 8
  ret void
}

t2.ll.S.merge:

// ABI signature returns S (as for objects without destructors)

define %t2.S @_D22t21S5mergeMFZSQBkQp(%t2.S* nocapture nonnull readonly
%.this_arg) local_unnamed_addr #1 comdat {

  %1 = getelementptr inbounds %t2.S, %t2.S* %.this_arg, i64 0, i32 0 ; [#uses = 
1, type = i8**]
  %.unpack = load i8*, i8** %1, align 8           ; [#uses = 1]
  %2 = insertvalue %t2.S undef, i8* %.unpack, 0 ; [#uses = 1]
  ret %t2.S %2
}

--


More information about the Digitalmars-d-bugs mailing list