https://gcc.gnu.org/g:b12d5a6ba64f09b9bbe57e6f49665df9b8b6fab0

commit r16-4171-gb12d5a6ba64f09b9bbe57e6f49665df9b8b6fab0
Author: Harald Anlauf <[email protected]>
Date:   Tue Sep 30 21:14:12 2025 +0200

    Fortran: UBSAN uninitialized stride for missing optional argument [PR122080]
    
            PR fortran/122080
    
    gcc/fortran/ChangeLog:
    
            * trans-array.cc (gfc_conv_array_parameter): Wrap the derivation of
            bounds and strides for the descriptor of an optional dummy array
            argument by a test on argument presence when it is supposed to be
            passed to an optional argument.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/ubsan/missing_optional_dummy_9.f90: New test.

Diff:
---
 gcc/fortran/trans-array.cc                         |  9 +++++++++
 .../gfortran.dg/ubsan/missing_optional_dummy_9.f90 | 22 ++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 0111c9566f41..db34de44401b 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -9446,6 +9446,15 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, 
bool g77,
 
          gfc_add_expr_to_block (&se->pre, tmp);
        }
+      else if (pass_optional && full_array_var && sym->as && sym->as->rank != 
0)
+       {
+         /* Perform calculation of bounds and strides of optional array dummy
+            only if the argument is present.  */
+         tmp = build3_v (COND_EXPR, gfc_conv_expr_present (sym),
+                         gfc_finish_block (&se->pre),
+                         build_empty_stmt (input_location));
+         gfc_add_expr_to_block (&se->pre, tmp);
+       }
     }
 
   /* Deallocate the allocatable components of structures that are
diff --git a/gcc/testsuite/gfortran.dg/ubsan/missing_optional_dummy_9.f90 
b/gcc/testsuite/gfortran.dg/ubsan/missing_optional_dummy_9.f90
new file mode 100644
index 000000000000..06b0004d5738
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ubsan/missing_optional_dummy_9.f90
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! { dg-options "-O2 -fdump-tree-original -fdump-tree-optimized 
-fsanitize=undefined" }
+!
+! PR fortran/122080 - UBSAN: uninitialized stride for missing actual argument
+!
+! Contributed by Henri Menke
+
+subroutine outer (optarr)
+  real, optional, intent(in) :: optarr(:,:)
+  interface
+     subroutine inner (optarr)
+       real, optional, intent(in) :: optarr(:,:)
+     end subroutine inner
+  end interface
+  call inner (optarr)
+end subroutine outer
+
+! There will be 2 remaining UBSAN checks of stride wrapped by a check
+! for argument presence:
+!
+! { dg-final { scan-tree-dump-times "if \\(optarr.0 != 0B\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "UBSAN_CHECK_SUB (.)* stride" 2 
"optimized" } }

Reply via email to