d: Fix no NRVO when returning an array of a non-POD struct
TREE_ADDRESSABLE was not propagated from the RECORD_TYPE to the ARRAY_TYPE, so NRVO code generation was not being triggered. gcc/d/ChangeLog: PR d/96157 * d-codegen.cc (d_build_call): Handle TREE_ADDRESSABLE static arrays. * types.cc (make_array_type): Propagate TREE_ADDRESSABLE from base type to static array. gcc/testsuite/ChangeLog: PR d/96157 * gdc.dg/pr96157a.d: New test. * gdc.dg/pr96157b.d: New test.
This commit is contained in:
parent
3eefc04663
commit
312ad889e9
4 changed files with 77 additions and 4 deletions
|
@ -1987,11 +1987,11 @@ d_build_call (TypeFunction *tf, tree callable, tree object,
|
|||
targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
|
||||
}
|
||||
|
||||
/* Parameter is a struct passed by invisible reference. */
|
||||
/* Parameter is a struct or array passed by invisible reference. */
|
||||
if (TREE_ADDRESSABLE (TREE_TYPE (targ)))
|
||||
{
|
||||
Type *t = arg->type->toBasetype ();
|
||||
StructDeclaration *sd = t->isTypeStruct ()->sym;
|
||||
StructDeclaration *sd = t->baseElemOf ()->isTypeStruct ()->sym;
|
||||
|
||||
/* Nested structs also have ADDRESSABLE set, but if the type has
|
||||
neither a copy constructor nor a destructor available, then we
|
||||
|
|
|
@ -186,8 +186,11 @@ make_array_type (Type *type, unsigned HOST_WIDE_INT size)
|
|||
return t;
|
||||
}
|
||||
|
||||
return build_array_type (build_ctype (type),
|
||||
build_index_type (size_int (size - 1)));
|
||||
tree t = build_array_type (build_ctype (type),
|
||||
build_index_type (size_int (size - 1)));
|
||||
/* Propagate TREE_ADDRESSABLE to the static array type. */
|
||||
TREE_ADDRESSABLE (t) = TREE_ADDRESSABLE (TREE_TYPE (t));
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Builds a record type whose name is NAME. NFIELDS is the number of fields,
|
||||
|
|
24
gcc/testsuite/gdc.dg/pr96157a.d
Normal file
24
gcc/testsuite/gdc.dg/pr96157a.d
Normal file
|
@ -0,0 +1,24 @@
|
|||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96157
|
||||
// { dg-do run { target native } }
|
||||
// { dg-skip-if "needs gcc/config.d" { ! d_runtime } }
|
||||
|
||||
struct S
|
||||
{
|
||||
@disable this(this); // triggers nrvo
|
||||
int v;
|
||||
}
|
||||
|
||||
__gshared void* p;
|
||||
|
||||
S[1000] foo() nothrow
|
||||
{
|
||||
typeof(return) d;
|
||||
p = &d;
|
||||
return d;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
auto d = foo();
|
||||
assert(p == &d);
|
||||
}
|
46
gcc/testsuite/gdc.dg/pr96157b.d
Normal file
46
gcc/testsuite/gdc.dg/pr96157b.d
Normal file
|
@ -0,0 +1,46 @@
|
|||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96157
|
||||
// { dg-options "-fno-moduleinfo -fno-rtti" }
|
||||
// { dg-do compile }
|
||||
|
||||
int[] testYearsBC;
|
||||
|
||||
struct FilterResult
|
||||
{
|
||||
int[] input;
|
||||
bool primed;
|
||||
|
||||
this(int[] r)
|
||||
{
|
||||
this.input = r;
|
||||
}
|
||||
|
||||
int front()
|
||||
{
|
||||
return input[0];
|
||||
}
|
||||
};
|
||||
|
||||
FilterResult filter(int[] range)
|
||||
{
|
||||
return FilterResult(range);
|
||||
}
|
||||
|
||||
int[] chain(int[] rs)
|
||||
{
|
||||
return rs;
|
||||
}
|
||||
|
||||
struct SysTime
|
||||
{
|
||||
this(int);
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
FilterResult val = filter(chain(testYearsBC));
|
||||
int year = val.front();
|
||||
SysTime(0);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue