[patch, Fortran] Fix undefined variable warnings related to ASSOCIATE

Thomas Koenig <[email protected]> Sat, 1 Aug 2026 15:26:36 +0200
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.fortran
Message-ID <[email protected]>
Hello world,

this fixes one of the false positives from the addition of the recent
-W options, with ASSOCIATE.

Regression-tested. OK for trunk?

Best regards

	Thomas

Fix undefined variable warning related to ASSOCIATE.

This patch fixes unused warnings in ASSOCIATE constructs by setting
value_used and value_set attributes based on the associate names.
This is placed after resolution of the code. To get to the association
list, an extra argument to gfc_resolve was needed.

gcc/fortran/ChangeLog:

	PR fortran/126558
	* gfortran.h (gfc_resolve): Add optional argument for
	an association list.
	* resolve.cc (mark_assoc_used): New function.
	(gfc_resolve): Use it.

gcc/testsuite/ChangeLog:

	PR fortran/126558
	* gfortran.dg/warn_undefined_vars_10.f90: New test.
p1.diff (text/x-patch, 2.9 KB)
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index df987576fff..0a8c6a853a0 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -4189,7 +4189,7 @@ bool gfc_op_rank_conformable (gfc_expr *, gfc_expr *);
 bool gfc_resolve_ref (gfc_expr *);
 void gfc_fixup_inferred_type_refs (gfc_expr *);
 bool gfc_resolve_expr (gfc_expr *);
-void gfc_resolve (gfc_namespace *);
+void gfc_resolve (gfc_namespace *, gfc_association_list *a = NULL);
 void gfc_resolve_code (gfc_code *, gfc_namespace *);
 void gfc_resolve_blocks (gfc_code *, gfc_namespace *);
 void gfc_resolve_formal_arglist (gfc_symbol *);
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 5f3edb37aa4..f4622375b84 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -12970,10 +12970,29 @@ resolve_block_construct (gfc_code* code)
 
   /* For an ASSOCIATE block, the associations (and their targets) will be
      resolved by gfc_resolve_symbol, during resolution of the BLOCK's
-     namespace.  */
-  gfc_resolve (ns);
+     namespace.  However, marking variables as used ans defined requires
+     passing ext.block.assoc.  */
+  gfc_resolve (ns, code->ext.block.assoc);
 }
 
+/* Mark everything in an association list as used and set if applicable,
+   respectively.  */
+
+static void
+mark_assoc_used (gfc_association_list *a)
+{
+  while (a != NULL)
+    {
+      gfc_symbol *n_sym = a->st->n.sym;
+      if (n_sym->attr.value_used != VALUE_UNUSED)
+	gfc_value_used_expr (a->target, n_sym->attr.value_used);
+
+      if (a->variable && n_sym->attr.value_set != VALUE_UNSET)
+	gfc_expr_set_at (a->target, &n_sym->other_loc, n_sym->attr.value_set);
+
+      a = a->next;
+    }
+}
 
 /* Resolve lists of blocks found in IF, SELECT CASE, WHERE, FORALL, GOTO and
    DO code nodes.  */
@@ -21031,7 +21050,7 @@ warn_unused_vs_set (gfc_namespace *ns)
    which functions or subroutines.  */
 
 void
-gfc_resolve (gfc_namespace *ns)
+gfc_resolve (gfc_namespace *ns, gfc_association_list *a)
 {
   gfc_namespace *old_ns;
   code_stack *old_cs_base;
@@ -21053,6 +21072,7 @@ gfc_resolve (gfc_namespace *ns)
   resolve_types (ns);
   component_assignment_level = 0;
   resolve_codes (ns);
+  mark_assoc_used (a);
 
   if (warn_unused_but_set_variable || warn_unused_intent_out
       || warn_unused_read || warn_undefined_vars)
diff --git a/gcc/testsuite/gfortran.dg/warn_undefined_vars_10.f90 b/gcc/testsuite/gfortran.dg/warn_undefined_vars_10.f90
new file mode 100644
index 00000000000..57c957143e4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/warn_undefined_vars_10.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! { dg-options "-Wundefined-vars" }
+! PR fortran/126558 - this used to give a false positive for y.
+
+program memain
+  implicit none
+  integer :: x,y
+  associate (ax => x)
+  end associate
+  print *, x ! { dg-warning "Undefined variable" }
+  associate (ay => y)
+    ay = 42
+  end associate
+  print *,y
+end program memain