[PATCH] Fortran [PR103367] Followup patch to fix related test cases
Jerry D <[email protected]> Mon, 6 Jul 2026 19:34:02 -0700
| Newsgroups | gmane.comp.gcc.patches,gmane.comp.gcc.fortran |
|---|---|
| Message-ID | <[email protected]> |
Hi all, A number of test cases, which are variations on the original reported problems on this PR, arrived on bugzilla. While working on there bugs I noticed some failures that I had originally seen on this one. This prompted me to get digging. The result after several iterations is the attached patch. Regression tested on x86_64. OK for mainline? and later we need to backport to fix the holes. Regards, Jerry --- fortran: [PR103367] Followup patch to fix related test cases PR fortran/103367 gcc/fortran/ChangeLog: * expr.cc (simplify_const_ref): Hoist the call to remove_subobject_ref up a level. * primary.cc (gfc_match_rvalue): Don't copy the value expr if the type is an EXPR_VARIABLE. not * trans-array.cc (gfc_conv_array_initializer): Only copy the expr value if it does not have a ref. gcc/testsuite/ChangeLog: * gfortran.dg/pr103367_2.f90: New test. * gfortran.dg/pr103367_3.f90: New test. * gfortran.dg/pr103367_4.f90: New test. ---
0001-fortran-PR103367-Followup-patch-to-fix-related-test-.patch
(text/x-patch, 5.7 KB)
From ef05aae9fd868870fd427f53731676642d45b29d Mon Sep 17 00:00:00 2001 From: Jerry DeLisle <[email protected]> Date: Mon, 6 Jul 2026 18:30:05 -0700 Subject: [PATCH] fortran: [PR103367] Followup patch to fix related test cases PR fortran/103367 gcc/fortran/ChangeLog: * expr.cc (simplify_const_ref): Hoist the call to remove_subobject_ref up a level. * primary.cc (gfc_match_rvalue): Don't copy the value expr if the type is an EXPR_VARIABLE. not * trans-array.cc (gfc_conv_array_initializer): Only copy the expr value if it does not have a ref. gcc/testsuite/ChangeLog: * gfortran.dg/pr103367_2.f90: New test. * gfortran.dg/pr103367_3.f90: New test. * gfortran.dg/pr103367_4.f90: New test. --- gcc/fortran/expr.cc | 24 ++++++++++----- gcc/fortran/primary.cc | 3 +- gcc/fortran/trans-array.cc | 3 +- gcc/testsuite/gfortran.dg/pr103367_2.f90 | 37 ++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/pr103367_3.f90 | 11 +++++++ gcc/testsuite/gfortran.dg/pr103367_4.f90 | 14 +++++++++ 6 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr103367_2.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr103367_3.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr103367_4.f90 diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc index 9fb152074db..946fa86a822 100644 --- a/gcc/fortran/expr.cc +++ b/gcc/fortran/expr.cc @@ -2162,16 +2162,26 @@ simplify_const_ref (gfc_expr *p) switch (p->ref->type) { case REF_ARRAY: - switch (p->ref->u.ar.type) + /* <type/kind spec>, parameter :: x(<int>) = scalar_expr + will generate this. */ + if (p->expr_type != EXPR_ARRAY) { - case AR_ELEMENT: - /* <type/kind spec>, parameter :: x(<int>) = scalar_expr - will generate this. */ - if (p->expr_type != EXPR_ARRAY) + if (p->ref->u.ar.type == AR_ELEMENT) { - remove_subobject_ref (p, NULL); - break; + int dim; + for (dim = 0; dim < p->ref->u.ar.dimen; dim++) + if (!p->ref->u.ar.start[dim] + || p->ref->u.ar.start[dim]->expr_type != EXPR_CONSTANT) + return true; } + + remove_subobject_ref (p, NULL); + break; + } + + switch (p->ref->u.ar.type) + { + case AR_ELEMENT: if (!find_array_element (p->value.constructor, &p->ref->u.ar, &cons)) return false; diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc index da517f8394f..d167036b808 100644 --- a/gcc/fortran/primary.cc +++ b/gcc/fortran/primary.cc @@ -4025,7 +4025,8 @@ gfc_match_rvalue (gfc_expr **result) end up here. Unfortunately, sym->value->expr_type is set to EXPR_CONSTANT, and so the if () branch would be followed without the !sym->as check. */ - if (sym->value && sym->value->expr_type != EXPR_ARRAY && !sym->as) + if (sym->value && sym->value->expr_type != EXPR_ARRAY + && sym->value->expr_type != EXPR_VARIABLE && !sym->as) e = gfc_copy_expr (sym->value); else { diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index d1153f5565c..11cf2ba2e86 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -6683,7 +6683,8 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr) if (expr->expr_type == EXPR_VARIABLE && expr->symtree->n.sym->attr.flavor == FL_PARAMETER - && expr->symtree->n.sym->value) + && expr->symtree->n.sym->value + && !expr->ref) expr = expr->symtree->n.sym->value; /* After parameter substitution the expression should be a constant, array diff --git a/gcc/testsuite/gfortran.dg/pr103367_2.f90 b/gcc/testsuite/gfortran.dg/pr103367_2.f90 new file mode 100644 index 00000000000..6a3c4f6357b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr103367_2.f90 @@ -0,0 +1,37 @@ +! { dg-do compile } +subroutine s1 + type t + integer :: a(1,2) = 3 + end type + type(t), parameter :: x(1) = t(4) + integer, parameter :: y(1,2) = (x(1)%a(m,1)) ! { dg-error "does not reduce to a constant expression" } + print *, y +end + +subroutine s2 + type t + integer :: a(2) = 3! + end type + type(t), parameter :: x(1) = t(4) + integer, parameter :: y = x(1)%a(m) ! { dg-error "non-constant initialization expression" } + print *, y +end + +subroutine s3 + type t + integer :: a(1,2) = 3 + end type + type(t), parameter :: x(1) = t(4) + integer, parameter :: y(1,2) = (x(b)%a) ! { dg-error "does not reduce to a constant expression" } + print *, y +end + +subroutine s4 + type t + integer :: a(1,2) = 3 + end type + type(t), parameter :: x(1) = t(4) + integer :: y(1,2) = x(b)%a ! { dg-error "does not reduce to a constant expression" } + print *, y +end +! { dg-prune-output "Legacy Extension: REAL array index" } diff --git a/gcc/testsuite/gfortran.dg/pr103367_3.f90 b/gcc/testsuite/gfortran.dg/pr103367_3.f90 new file mode 100644 index 00000000000..6c83e88b28d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr103367_3.f90 @@ -0,0 +1,11 @@ +! { dg-do run } +! PR103367 Test case from the PR, previously segfaulted. +program p + type t + integer :: a(1,2) = 3 + end type + type(t), parameter :: x(1) = t(4) + integer, parameter :: y(2) = x(1)%a(1,:) + if (any (y /= [4, 4])) stop 1 +end + diff --git a/gcc/testsuite/gfortran.dg/pr103367_4.f90 b/gcc/testsuite/gfortran.dg/pr103367_4.f90 new file mode 100644 index 00000000000..e0c052692cd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr103367_4.f90 @@ -0,0 +1,14 @@ +! { dg-do run } +! PR103367, this test previously +! Test case from the PR segfaulted at compile time. +program p + type inner + integer :: n = 3 + end type + type outer + type(inner) :: a(2) = inner(1) + end type + type(outer), parameter :: x(1) = outer(inner(4)) + integer, parameter :: y(2) = x(1)%a%n + if (any (y /= [4, 4])) stop 1 +end -- 2.54.0