[gcc r17-2596] Fix a few false positive warnings with unused/undefined warnings.

Thomas Koenig via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:ea991f752fc2a65a887c64190d8cad415edac8c9

commit r17-2596-gea991f752fc2a65a887c64190d8cad415edac8c9
Author: Thomas Koenig <[email protected]>
Date:   Tue Jul 21 19:04:48 2026 +0200

    Fix a few false positive warnings with unused/undefined warnings.
    
    Trying out the new warnings on actual code found a new false positives.
    The charlen of an ALLOCATE was not marked as used, the expression
    in SELECT CASE was not marked as used and host-associated variables
    were not exempt from testing.
    
    All fixed with the attached patch.
    
    gcc/fortran/ChangeLog:
    
            PR fortran/126333
            * resolve.cc (resolve_allocate_deallocate): Resolve charlen of ts
            and set as used if present.
            (resolve_select): Mark code->expr1 as used.
            (find_unused_vs_set): Do not complain about host-associated
            variables which are not marked private.
    
    gcc/testsuite/ChangeLog:
    
            PR fortran/126333
            * gfortran.dg/warn_undefined_vars_8.f90: New test.
            * gfortran.dg/warn_undefined_vars_9.f90: New test.
            * gfortran.dg/warn_unused_but_set_variable_5.f90: New test.

Diff:
---
 gcc/fortran/resolve.cc                             | 15 +++++++++++++
 .../gfortran.dg/warn_undefined_vars_8.f90          | 17 +++++++++++++++
 .../gfortran.dg/warn_undefined_vars_9.f90          | 18 ++++++++++++++++
 .../gfortran.dg/warn_unused_but_set_variable_5.f90 | 25 ++++++++++++++++++++++
 4 files changed, 75 insertions(+)

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 6dc1b8e315d5..5f3edb37aa4b 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -9961,6 +9961,14 @@ done_errmsg:
     {
       bool arr_alloc_wo_spec = false;
 
+      /* Resolve and mark as used the length of the type spec.  */
+      if (code->ext.alloc.ts.type == BT_CHARACTER)
+	{
+	  gfc_expr *length = code->ext.alloc.ts.u.cl->length;
+	  gfc_resolve_expr (length);
+	  gfc_value_used_expr (length, VALUE_USED);
+	}
+
       /* Resolving the expr3 in the loop over all objects to allocate would
 	 execute loop invariant code for each loop item.  Therefore do it just
 	 once here.  */
@@ -10274,6 +10282,7 @@ resolve_select (gfc_code *code, bool select_type)
 	 GOTOs as normal SELECTs from here on.  */
       code->expr1 = code->expr2;
       code->expr2 = NULL;
+      gfc_value_used_expr (code->expr1, VALUE_USED);
       return;
     }
 
@@ -10542,6 +10551,9 @@ resolve_select (gfc_code *code, bool select_type)
     gfc_warning (OPT_Wsurprising,
 		 "Logical SELECT CASE block at %L has more that two cases",
 		 &code->loc);
+
+  /* Finally, mark the expression as used.  */
+  gfc_value_used_expr (case_expr, VALUE_USED);
 }
 
 
@@ -20840,6 +20852,9 @@ find_unused_vs_set (gfc_symbol *sym)
       || attr->volatile_ || attr->asynchronous || !attr->referenced)
     return;
 
+  if (attr->host_assoc && attr->access != ACCESS_PRIVATE)
+    return;
+
   /* There is no allocation in sight, but the variable is used anyway.  This
      might be hidden behind PRESENT, but issue a warning nonetheless.  If
      people complain, we might want to make this to an extra option to be
diff --git a/gcc/testsuite/gfortran.dg/warn_undefined_vars_8.f90 b/gcc/testsuite/gfortran.dg/warn_undefined_vars_8.f90
new file mode 100644
index 000000000000..2783745a8baf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/warn_undefined_vars_8.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! { dg-additional-options "-Wundefined-vars" }
+! A variable referenced in a charlen was not tracked for warnings.
+
+program memain
+  implicit none
+  character(len=:), allocatable :: c, d
+  integer :: n, m
+  n = 42
+  allocate (character(len=n) :: c)
+  read (*,*) c
+  print *,c
+  ! m = 21
+  allocate (character(len=m) :: d) ! { dg-warning "Undefined variable" }
+  read (*,*) d
+  print *,d
+end program memain
diff --git a/gcc/testsuite/gfortran.dg/warn_undefined_vars_9.f90 b/gcc/testsuite/gfortran.dg/warn_undefined_vars_9.f90
new file mode 100644
index 000000000000..59715c2e11bf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/warn_undefined_vars_9.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-additional-options "-Wundefined-vars" }
+! In the code below, a can be allocated by calling bar and
+! c from the outside.
+module x
+  implicit none
+  integer, allocatable, private, dimension(:) :: a, b
+  integer, allocatable, public, dimension(:) :: c
+contains
+  subroutine foo
+    print *,a
+    print *,b ! { dg-warning "Unallocated variable" }
+    print *,c
+  end subroutine foo
+  subroutine bar
+    a = [1,2,3]
+  end subroutine bar
+end module x
diff --git a/gcc/testsuite/gfortran.dg/warn_unused_but_set_variable_5.f90 b/gcc/testsuite/gfortran.dg/warn_unused_but_set_variable_5.f90
new file mode 100644
index 000000000000..00ff87365c4f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/warn_unused_but_set_variable_5.f90
@@ -0,0 +1,25 @@
+! { dg-do compile }
+! { dg-additional-options "-Wunused-but-set-variable" }
+
+module x
+  implicit none
+contains
+  function asdf() result(res)
+    character(len=1) :: res
+    integer :: i
+    read (*,*) i
+    select case(i)
+    case(1)
+       res = 'a'
+    case(2)
+       res = 's'
+    case(3)
+       res = 'd'
+    case(4)
+       res = 'f'
+    case default
+       res = ' '
+    end select
+  end function asdf
+end module x
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.