https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110241
Bug ID: 110241 Summary: Redundant temporaries passing empty array constructors Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: anlauf at gcc dot gnu.org Target Milestone: --- Found while working on pr86277: program p call sub ([real :: 42.]) ! Single temporary call sub ([real :: ]) ! Double temporary contains subroutine sub (arg) real, intent(in), optional :: arg(:) if (.not. present (arg)) stop 1 end end The dump-tree (at r14-1795-gc1691509e5a887) shows the following for the first call: { static real(kind=4) A.4[1] = {4.2e+1}; struct array01_real(kind=4) parm.5; parm.5.span = 4; parm.5.dtype = {.elem_len=4, .rank=1, .type=3}; parm.5.dim[0].lbound = 1; parm.5.dim[0].ubound = 1; parm.5.dim[0].stride = 1; parm.5.data = (void *) &A.4[0]; parm.5.offset = -1; sub (&parm.5); } which is as expected, but for the second call: { struct array01_real(kind=4) atmp.6; real(kind=4) A.7[0]; struct array01_real(kind=4) atmp.9; real(kind=4) A.10[0]; typedef real(kind=4) [0]; atmp.6.dtype = {.elem_len=4, .rank=1, .type=3}; atmp.6.dim[0].stride = 1; atmp.6.dim[0].lbound = 0; atmp.6.dim[0].ubound = -1; atmp.6.span = 4; atmp.6.data = (void * restrict) &A.7; atmp.6.offset = 0; typedef real(kind=4) [0]; atmp.9.dtype = {.elem_len=4, .rank=1, .type=3}; atmp.9.dim[0].stride = 1; atmp.9.dim[0].lbound = 0; atmp.9.dim[0].ubound = -1; atmp.9.span = 4; atmp.9.data = (void * restrict) &A.10; atmp.9.offset = 0; { integer(kind=8) S.11; S.11 = 0; while (1) { if (S.11 >= 0) goto L.2; (*(real(kind=4)[0] * restrict) atmp.9.data)[S.11] = (*(real(kind=4)[0] * restrict) atmp.6.data)[S.11]; S.11 = S.11 + 1; } L.2:; } sub (&atmp.9); } While this is at least correct code (as opposed to before the fix for pr86277), it could be as simple as for the non-empty constructor. (There's a patch attached to the other pr demonstrating that this can be achieved for this code snippet).