[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 +