mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
Fix bugzilla 24577 - Struct with constructor returned from C++ wrong
The test case is copied from LDC, where it already worked. It also has an additional test for a member struct with constructor.
This commit is contained in:
parent
db92f687e4
commit
56a21cba42
3 changed files with 194 additions and 0 deletions
|
@ -1009,6 +1009,8 @@ extern (C++) struct Target
|
|||
auto sd = ts.sym;
|
||||
if (tf.linkage == LINK.cpp && needsThis)
|
||||
return true;
|
||||
if (tf.linkage == LINK.cpp && sd.ctor)
|
||||
return true;
|
||||
if (!sd.isPOD() || sz > 8)
|
||||
return true;
|
||||
if (sd.fields.length == 0)
|
||||
|
|
74
compiler/test/runnable_cxx/extra-files/cpp_nonpod_byval.cpp
Normal file
74
compiler/test/runnable_cxx/extra-files/cpp_nonpod_byval.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
extern "C" int printf(const char *, ...);
|
||||
|
||||
#define Foo(T) \
|
||||
T fooD(T param); \
|
||||
T fooCpp(T param) \
|
||||
{ \
|
||||
printf("fooCpp %d [%p]\n", param.a, ¶m); \
|
||||
return fooD(T{2 * param.a}); \
|
||||
}
|
||||
|
||||
struct POD
|
||||
{
|
||||
int a;
|
||||
};
|
||||
Foo(POD);
|
||||
|
||||
struct CtorOnly
|
||||
{
|
||||
int a;
|
||||
CtorOnly() : a(0) {}
|
||||
CtorOnly(int a) : a(a) {}
|
||||
};
|
||||
Foo(CtorOnly);
|
||||
|
||||
struct DtorOnly
|
||||
{
|
||||
int a;
|
||||
~DtorOnly(); // implemented in D
|
||||
};
|
||||
Foo(DtorOnly);
|
||||
|
||||
struct CtorDtor
|
||||
{
|
||||
int a;
|
||||
CtorDtor(int a) : a(a) {}
|
||||
~CtorDtor(); // implemented in D
|
||||
};
|
||||
Foo(CtorDtor);
|
||||
|
||||
struct Copy
|
||||
{
|
||||
int a;
|
||||
Copy(int a) : a(a) {}
|
||||
~Copy(); // implemented in D
|
||||
Copy(const Copy &rhs) : a(rhs.a) { printf("cppcpy %d [%p]\n", a, this); }
|
||||
};
|
||||
Foo(Copy);
|
||||
|
||||
struct CopyAndMove
|
||||
{
|
||||
int a;
|
||||
CopyAndMove(int a) : a(a) {}
|
||||
~CopyAndMove(); // implemented in D
|
||||
CopyAndMove(const CopyAndMove &rhs) : a(rhs.a) { printf("cppcpy %d [%p]\n", a, this); }
|
||||
CopyAndMove(CopyAndMove &&) = default;
|
||||
};
|
||||
Foo(CopyAndMove);
|
||||
|
||||
struct MoveOnly
|
||||
{
|
||||
int a;
|
||||
MoveOnly(int a) : a(a) {}
|
||||
~MoveOnly(); // implemented in D
|
||||
MoveOnly(const MoveOnly &) = delete;
|
||||
MoveOnly(MoveOnly &&) = default;
|
||||
};
|
||||
Foo(MoveOnly);
|
||||
|
||||
struct MemberWithCtor
|
||||
{
|
||||
int a;
|
||||
CtorOnly m;
|
||||
};
|
||||
Foo(MemberWithCtor);
|
118
compiler/test/runnable_cxx/nonpod_byval.d
Normal file
118
compiler/test/runnable_cxx/nonpod_byval.d
Normal file
|
@ -0,0 +1,118 @@
|
|||
// EXTRA_CPP_SOURCES: cpp_nonpod_byval.cpp
|
||||
// CXXFLAGS(linux osx freebsd dragonflybsd): -std=c++11
|
||||
|
||||
extern (C) int printf(const(char)*, ...);
|
||||
|
||||
extern (C++):
|
||||
|
||||
template Foo(T)
|
||||
{
|
||||
T fooCpp(T param); // calls fooD() with a new, doubled literal
|
||||
|
||||
T fooD(T param)
|
||||
{
|
||||
printf("fooD %d [%p]\n", param.a, ¶m);
|
||||
assert(param.a == 2 * 123);
|
||||
static if (__traits(compiles, { T copy = param; }))
|
||||
return param; // invokes postblit
|
||||
else
|
||||
return T(param.a);
|
||||
}
|
||||
}
|
||||
|
||||
void test(T)()
|
||||
{
|
||||
printf(".: %.*s\n", cast(int) T.stringof.length, T.stringof.ptr);
|
||||
|
||||
{
|
||||
auto result = fooCpp(T(123));
|
||||
assert(result.a == 246);
|
||||
}
|
||||
|
||||
static if (__traits(hasMember, T, "numDtor"))
|
||||
{
|
||||
// fooCpp param + fooD param + result => 3 T instances.
|
||||
// There may be an additional destruction of the moved-from T literal
|
||||
// in fooCpp, depending on in-place construction vs. move.
|
||||
assert(T.numDtor == 3 || T.numDtor == 4);
|
||||
}
|
||||
}
|
||||
|
||||
struct POD
|
||||
{
|
||||
int a;
|
||||
}
|
||||
mixin Foo!POD;
|
||||
|
||||
struct CtorOnly
|
||||
{
|
||||
int a;
|
||||
this(int a) { this.a = a; }
|
||||
}
|
||||
mixin Foo!CtorOnly;
|
||||
|
||||
struct DtorOnly
|
||||
{
|
||||
static __gshared int numDtor = 0;
|
||||
int a;
|
||||
~this() { printf("dtor %d [%p]\n", a, &this); ++numDtor; }
|
||||
}
|
||||
mixin Foo!DtorOnly;
|
||||
|
||||
struct CtorDtor
|
||||
{
|
||||
static __gshared int numDtor = 0;
|
||||
int a;
|
||||
this(int a) { this.a = a; }
|
||||
~this() { printf("dtor %d [%p]\n", a, &this); ++numDtor; }
|
||||
}
|
||||
mixin Foo!CtorDtor;
|
||||
|
||||
struct Copy
|
||||
{
|
||||
static __gshared int numDtor = 0;
|
||||
int a;
|
||||
this(int a) { this.a = a; }
|
||||
~this() { printf("dtor %d [%p]\n", a, &this); ++numDtor; }
|
||||
this(this) { printf("post %d [%p]\n", a, &this); }
|
||||
}
|
||||
mixin Foo!Copy;
|
||||
|
||||
struct CopyAndMove
|
||||
{
|
||||
static __gshared int numDtor = 0;
|
||||
int a;
|
||||
this(int a) { this.a = a; }
|
||||
~this() { printf("dtor %d [%p]\n", a, &this); ++numDtor; }
|
||||
this(this) { printf("post %d [%p]\n", a, &this); }
|
||||
}
|
||||
mixin Foo!CopyAndMove;
|
||||
|
||||
struct MoveOnly
|
||||
{
|
||||
static __gshared int numDtor = 0;
|
||||
int a;
|
||||
this(int a) { this.a = a; }
|
||||
~this() { printf("dtor %d [%p]\n", a, &this); ++numDtor; }
|
||||
this(this) @disable;
|
||||
}
|
||||
mixin Foo!MoveOnly;
|
||||
|
||||
struct MemberWithCtor
|
||||
{
|
||||
int a;
|
||||
CtorOnly m;
|
||||
}
|
||||
mixin Foo!MemberWithCtor;
|
||||
|
||||
void main()
|
||||
{
|
||||
test!POD();
|
||||
test!CtorOnly();
|
||||
test!DtorOnly();
|
||||
test!CtorDtor();
|
||||
test!Copy();
|
||||
test!CopyAndMove();
|
||||
test!MoveOnly();
|
||||
test!MemberWithCtor();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue