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:
Iain Buclaw 2020-08-25 00:39:17 +02:00
parent 3eefc04663
commit 312ad889e9
4 changed files with 77 additions and 4 deletions

View file

@ -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

View file

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

View 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);
}

View 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);
}
}