[patch, fortran] Iplement warning based on variable definition and use
Thomas Koenig
tkoenig@netcologne.de
Tue Jun 9 05:14:25 GMT 2026
Hello world,
like it says in the ChangeLog below. There is a chance that this
may still generate some false positives. I tried to follow
Fortran terminology in the error messages, at least.
Regression-tested. Did I miss anything? OK for trunk?
Best regards
Thomas
Implement warnings based on variable definition and use.
This patch grew from trying to implement PR 30438 into something bigger.
This now warns about variables which were never defined, but are used
via a new option -Wundefined-vars and implements
-Wunused-but-set-variable for Fortran.
It works by keeping tabls of several things in the attributes of a
variable: If and how it has been set (via value_set), used (via
value_used), if it has been allocated (via allocated) and if a
warning has already been emitted for the symbol. This looks at
statements in a namespace only; control flow is *not* considered.
In every corner of the compiler that I could find where values are
set or used, flags are set accodingly. Updates are done if the new
use is considered to be more "important" than the old one. The
location of use or definition is also recorded, as is the place
where a variable may be allocated.
After all the flags have been correctly set (one at least hopes)
gfc_resolve then calls warn_unused_vs_set, which then iterates
over the symbols, calling find_unused_vs_set where all warnings
are emitted. I tried to be conservative here to avoid false
positives, so a whole lot of conditions are excluded (see the top
of the function).
I thought a bit on where to put -Wunused-read and -Wunused-intent-out.
While reading in a value and then not using it, or getting it from an
INTENT(OUT) argument may be dubious, people could use it for skipping
over unneeded data or because an API requires it. Hence, I feld that -Wall
would be too harsh, but I am open to discussion here.
The warn_undefined_vars_* tests are split because the testsuite would
not find warnings in certain lines even though they were issued and
I tried out ! { dg-warning ".+" } . I suspect some strangeness/bug
in gfortran.dg, but did not investigate further.
gcc/fortran/ChangeLog:
PR fortran/30438
PR fortran/28004
* dump-parse-tree.cc (gfc_debug_code_node): New function.
(show_attr): Add select_rank_temporary. Fix typo. Add referenced,
value_set, allocated and value_used.
* gfortran.h (enum value_set): New enum.
(enum value_used): New enum.
(gfc_symbol): Add value_set, value_used, allocated and
warning_emitted attributes. Rename formal_at to other_loc.
Add extra_loc.
(gfc_value_set_at): Add prototype.
(gfc_lvalue_allocated_at): Likewise.
(gfc_mark_lhs_as_used): Likewise.
(gfc_value_used_expr): Likewise.
(gfc_value_set_and_used): Likewise.
(gfc_used_in_allocate_expr): Likewise.
* interface.cc (gfc_compare_actual_formal): Mark actual arguments
according to INTENT and VALUE on formal arguments.
(gfc_procedure_use): Add VALUE_ARG/VALUE_MAYBE_USED for
implicit arguments.
* intrinsic.cc (mark_args_as_used): New function.
(init_arglist): Adjust comment.
(gfc_intrinsic_sub_interface): Use mark_args_as_used.
* invoke.texi: Document -Wundefined-vars, -Wunused-intent-out and
-Wunused-read.
* io.cc (resolve_tag_format): Mark expressions as used.
(resolve_tag): Mark as used or set, depending on tag.
(gfc_resolve_dt): Mark internal unit as set.
(gfc_resolve_inquire): Mark value as set for INQUIRE_RESOLVE_TAG macro.
* lang.opt: Add -Wundefined-vars, -Wunused-intent-out and -Wunused-read.
* lang.opt.urls: Regenerated.
* resolve.cc (resolve_function): Replace formal_at by other_loc.
(resolve_call): Likewise.
(gfc_resolve_iterator): Mark iterator variable as set and used and
other expressions as used.
(resolve_forall_iterators): Likewise.
(resolve_allocate_expr): On success, call gfc_used_in_allocate_expr
and mark value as set if source is present.
(resolve_transfer): Mark set/read according to context.
(gfc_resolve_blocks): Mark expr1 and expr2 as used.
(mark_lhs_assignments_set): Prototype / new function.
(gfc_resolve_code): Mark expr2, expr3 and expr4 as used.
(var_value_is_used): New function.
(var_value_is_set): New function.
(find_unused_vs_set): New function.
(warn_unused_vs_set): New function.
(gfc_resolve): Call warn_unused_vs_set.
* symbol.cc (gfc_value_set_at): New function.
(mark_vars_as_used): New function.
(gfc_value_used_expr): New function.
(gfc_value_set_and_used): New function.
(gfc_used_in_allocate_expr): new function.
(gfc_lvalue_allocated_at): New function.
* trans-decl.cc (gfc_finish_var_decl): If we already emitted a warning,
suppress further middle-end warning o that variable.
libgfortran/ChangeLog:
PR fortran/30438
PR fortran/28004
* mk-kinds-h.sh: Add print statement so test will compile with -Wall
-Werror.
* mk-sik-inc.sh: Likewise.
* mk-srk-inc.sh: Likewise.
libgomp/ChangeLog:
PR fortran/30438
PR fortran/28004
* testsuite/libgomp.fortran/alloc-1.F90: Shut up -Wunused-but-set-variable.
* testsuite/libgomp.fortran/alloc-12.f90: Likewise.
gcc/testsuite/ChangeLog:
PR fortran/30438
PR fortran/28004
* gfortran.dg/allocatable_length.f90: Add -Wno-undefined-vars.
* gfortran.dg/allocatable_scalar_6.f90: Likewise.
* gfortran.dg/allocatable_uninitialized_1.f90: Add
-Wno-unused-but-set-variable
-Wno-undefined-vars.
* gfortran.dg/assignment_4.f90: Add -Wno-undefined-vars.
* gfortran.dg/attr_deprecated-2.f90: Likewise.
* gfortran.dg/c_by_val_5.f90: Add -Wno-unused-but-set-variable.
* gfortran.dg/char_component_initializer_2.f90: Shut up warning.
* gfortran.dg/char_length_1.f90: Add statement to shut up warning.
* gfortran.dg/constructor_9.f90: Add -Wno-unused-but-set-variable.
* gfortran.dg/gamma_2.f90: Add statement to shut up warning.
* gfortran.dg/gomp/allocate-10.f90: Add -Wno-unused-but-set-variable.
* gfortran.dg/io_constraints_8.f90: Likewise.
* gfortran.dg/label_5.f90: Likewise.
* gfortran.dg/len_trim.f90: Likewise.
* gfortran.dg/linefile.f90: Likewise.
* gfortran.dg/pointer_check_13.f90: Add dg-warning.
* gfortran.dg/pr102366.f90: Add -Wno-unused-but-set-variable.
* gfortran.dg/pr103475.f90: Likewise.
* gfortran.dg/pr91497.f90: Likewise.
* gfortran.dg/pr91497_2.f90: Likewise.
* gfortran.dg/pr96312.f90: Likewise.
* gfortran.dg/pr98411.f90: Likewise.
* gfortran.dg/transfer_check_4.f90: Likewise.
* gfortran.dg/warnings_are_errors_1.f90: Add print statement.
* gfortran.dg/warn_undefined_vars_1.f90: New test.
* gfortran.dg/warn_undefined_vars_2.f90: New test.
* gfortran.dg/warn_undefined_vars_3.f90: New test.
* gfortran.dg/warn_undefined_vars_4.f90: New test.
* gfortran.dg/warn_unused_intent_out_1.f90: New test.
* gfortran.dg/warn_unused_read_1.f90: New test.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: p11b.diff
Type: text/x-patch
Size: 57168 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/fortran/attachments/20260609/7ce56c54/attachment-0001.bin>
More information about the Fortran
mailing list