[Bug middle-end/90501] [10 regression] ICE: address taken, but ADDRESSABLE bit not set

ibuclaw at gdcproject dot org gcc-bugzilla@gcc.gnu.org
Thu May 16 17:18:00 GMT 2019


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90501

--- Comment #11 from Iain Buclaw <ibuclaw at gdcproject dot org> ---
(In reply to Jakub Jelinek from comment #8)
> So the first question would be why D passes the return value as
> DECL_BY_REFERENCE if it doesn't have TREE_ADDRESSABLE type.

Looking at the places where DECL_BY_REFERENCE is set, this mismatch could
happen when the result should be returned using NRVO.

To memory, using a mixture of DECL_BY_REFERENCE and CALL_EXPR_RETURN_SLOT_OPT
gives a desired behaviour of eliding a copy.

Two things come to mind as alternatives:

1. Currently for NRVO, the DECL_RESULT is explicitly set as not addressable.

  TREE_TYPE (resdecl) = build_reference_type (TREE_TYPE (resdecl));
  DECL_BY_REFERENCE (resdecl) = 1;
  TREE_ADDRESSABLE (resdecl) = 0;

Is it allowed for the decl to be both DECL_BY_REFERENCE and TREE_ADDRESSABLE at
the same time?  Or will that just confuse things further.

  TREE_TYPE (resdecl) = build_reference_type (TREE_TYPE (resdecl));
  DECL_BY_REFERENCE (resdecl) = 1;
- TREE_ADDRESSABLE (resdecl) = 0;
+ if (TREE_ADDRESSABLE (TREE_TYPE (resdecl))
+   TREE_ADDRESSABLE (resdecl) = 0;


2. Redo handling of NRVO in the D front-end, to enforce a specific semantic for
trivial types that we want to elide a copy for.

i.e: Given,
---
S foo()
{
    S result;
    result.a = 3;
    return result;
}

void test()
{
    S s = foo();
}
---

Generate this explicitly as:
---
S* foo(S* hidden)
{
    S result;
    result.a = 3;
    *hidden = result;
    return hidden;
}

void test()
{
    S tmp;
    S s = *foo(&tmp);
}
---

Obviously, that change would be a bit more involved on my side.


More information about the Gcc-bugs mailing list