[gcc r14-12423] fortran: Fix UB in transfer_expr [PR124450]

Jakub Jelinek jakub@gcc.gnu.org
Sun Mar 15 06:11:26 GMT 2026


https://gcc.gnu.org/g:82a71e3590841cfc85e5f5669aeef0c6f54dca50

commit r14-12423-g82a71e3590841cfc85e5f5669aeef0c6f54dca50
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu Mar 12 12:39:43 2026 +0100

    fortran: Fix UB in transfer_expr [PR124450]
    
    trans-io.cc (transfer_array_component) calls transfer_expr with
    NULL code:
      transfer_expr (&se, &cm->ts, tmp, NULL, NULL_TREE);
    I'm surprised it doesn't ICE in other spots that dereference
    code->whatever but each one is guarded with some condition
    that perhaps don't trigger in that case for some reason.
    Anyway, the &code->loc case does trigger, it doesn't ICE, but
    it is undefined behavior in the compiler when code is NULL,
    and we'd crash if the where argument of 3*sizeof(void*) is
    dereferenced.  Code I've checked can handle NULL where though.
    
    2026-03-12  Jakub Jelinek  <jakub@redhat.com>
    
            PR fortran/124450
            * trans-io.cc (transfer_expr): If code is NULL, call
            transfer_array_component with NULL where argument rather than
            &code->loc.
    
            * gfortran.dg/pr124450.f90: New test.
    
    (cherry picked from commit adefcfed81e19aa250f34914182a7c5580dc6e2a)

Diff:
---
 gcc/fortran/trans-io.cc                |  4 +++-
 gcc/testsuite/gfortran.dg/pr124450.f90 | 14 ++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-io.cc b/gcc/fortran/trans-io.cc
index c5ca8787db36..e34629794d5b 100644
--- a/gcc/fortran/trans-io.cc
+++ b/gcc/fortran/trans-io.cc
@@ -2496,7 +2496,9 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr,
 
 		  if (c->attr.dimension)
 		    {
-		      tmp = transfer_array_component (tmp, c, & code->loc);
+		      tmp = transfer_array_component (tmp, c,
+						      code ? &code->loc
+						      : NULL);
 		      gfc_add_expr_to_block (&se->pre, tmp);
 		    }
 		  else
diff --git a/gcc/testsuite/gfortran.dg/pr124450.f90 b/gcc/testsuite/gfortran.dg/pr124450.f90
new file mode 100644
index 000000000000..b6d9abc1c85f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr124450.f90
@@ -0,0 +1,14 @@
+! PR fortran/124450
+! { dg-do compile }
+
+  type ta
+    integer(kind=4) :: a(1)
+    integer(kind=4) :: b(1)
+  end type ta
+  type tb
+    type(ta) :: c(1) = ta(1, 2)
+  end type tb
+  type(tb) :: e = tb(ta(3, 4))
+
+  print *, e
+end


More information about the Gcc-cvs mailing list