]> git.ipfire.org Git - thirdparty/gcc.git/commit
fortran: Honor array constructor type-spec during folding [PR107721]
authorChristopher Albert <albert@tugraz.at>
Mon, 24 Nov 2025 23:13:03 +0000 (00:13 +0100)
committerHarald Anlauf <anlauf@gmx.de>
Mon, 1 Dec 2025 19:46:26 +0000 (20:46 +0100)
commitc50d263beff78ab1133ccff1de78a50ea4851d7e
tree4d9defeb18773dd8fa4b9e3ffcb042c97966311d
parent4d1bfc66f84de6b37b175a191cba8cdd552c4383
fortran: Honor array constructor type-spec during folding [PR107721]

When an array constructor has an explicit type-spec, all elements must be
converted to that type and character elements must be padded/truncated to
the specified length.  This was working for simple cases but failing when:

1. Elements were parenthesized: [integer :: ([1.0])]
2. Constructors were nested: [[integer :: [1.0]]]
3. Character constructors were used with concatenation operators:
   [character(16) :: 'a', 'b'] // '|'
4. Nested character constructors with concatenation:
   [character(16) :: ['a', 'b']] // '|'
5. Outer constructor without type-spec wrapping inner with type-spec:
   [[character(16) :: ['a', 'b']]] // '|'
6. Nested character constructors with different type-specs:
   [character(16) :: [character(2) :: 'abcd']]

The root cause was twofold:

First, parenthesized expressions like ([1.0]) create EXPR_OP nodes that were
not being simplified before type conversion in check_constructor_type(),
so type conversion was applied to the EXPR_OP rather than its contents.

Second, character array constructors with explicit type-spec were not being
resolved before CONCAT operations in eval_intrinsic(), so elements retained
their original lengths instead of being padded to the type-spec length.
Additionally, nested array constructors needed their type-spec propagated
from the outer constructor.

The fix adds:
- Simplification of non-constant expressions in check_constructor_type()
  before attempting type conversion
- Call to gfc_check_constructor_type() in eval_intrinsic() to ensure
  type-spec conversion happens before any operations on array constructors
- Character array constructor resolution before CONCAT operations
- Recursive type-spec propagation for nested array constructors.
  When a nested array constructor has its own explicit type-spec, it is
  resolved first to enforce its own length (truncation/padding) before
  propagating the outer type-spec and resolving again.
- Detection of nested character constructors with explicit type-spec
  (via length_from_typespec) when the outer constructor has no type-spec

PR fortran/107721
PR fortran/102417

gcc/fortran/ChangeLog:

* arith.cc (eval_intrinsic): Call gfc_check_constructor_type on
array constructor operands with explicit type-spec to ensure
element type conversion before operations.  Resolve character
array constructors before CONCAT operations.
(reduce_binary_ac, reduce_binary_ca, reduce_binary_aa): Preserve
character length info in result arrays.
* array.cc (check_constructor_type): Simplify non-constant
expressions before type checking to handle parenthesized elements.
Handle nested character array constructors with explicit type-spec
when outer constructor has no type-spec.
(gfc_resolve_character_array_constructor): Recursively propagate
type-spec to nested array constructors.  If the nested constructor
has an explicit type-spec, resolve it first before propagating
the outer type-spec.

gcc/testsuite/ChangeLog:

* gfortran.dg/array_constructor_typespec_1.f90: New test.

Co-authored-by: Harald Anlauf <anlauf@gcc.gnu.org>
Signed-off-by: Christopher Albert <albert@tugraz.at>
gcc/fortran/arith.cc
gcc/fortran/array.cc
gcc/testsuite/gfortran.dg/array_constructor_typespec_1.f90 [new file with mode: 0644]