Hello world,
what it says in the ChangeLog. Regression-tested. OK for trunk?
Best regards
Thomas
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 --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 6dc1b8e315d..5f3edb37aa4 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 00000000000..2783745a8ba
--- /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 00000000000..59715c2e11b
--- /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 00000000000..00ff87365c4
--- /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
+