[gcc r17-2878] Fix undefined variable warning in ASSOCIATE.

Thomas Koenig via Gcc-cvs <[email protected]> Sat, 1 Aug 2026 17:13:32 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:6bf6dad534766300376dec6d093d49b89a452ea1

commit r17-2878-g6bf6dad534766300376dec6d093d49b89a452ea1
Author: Thomas Koenig <[email protected]>
Date:   Sat Aug 1 19:03:38 2026 +0200

    Fix undefined variable warning in 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.

Diff:
---
 gcc/fortran/gfortran.h                             |  2 +-
 gcc/fortran/resolve.cc                             | 26 +++++++++++++++++++---
 .../gfortran.dg/warn_undefined_vars_10.f90         | 15 +++++++++++++
 3 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 807756d6a170..cb08a6098284 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -4194,7 +4194,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 94bb3362fe33..bae889791df6 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.  */
@@ -21037,7 +21056,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;
@@ -21059,6 +21078,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 000000000000..57c957143e42
--- /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