This patch fixes an ICE due to a null-pointer dereference when finding the symbol for the procedure name in a declare variant directive, which occurs because the result of gfc_find_sym_tree is being dereferenced unconditionally. The result is now checked, and the symbol is set to NULL if it can't be found, resulting in a subsequent error.

If the symbol is implicitly typed, then the error will also occur. I think this makes sense as implicit variables are of type integer or real, which cannot be used to specify the variant procedure.

Tested on x86_64 host, okay for trunk?

Kwok
From 5b76d307bc4328c9ee580cfadccd3225837dce37 Mon Sep 17 00:00:00 2001
From: Kwok Cheung Yeung <kcye...@baylibre.com>
Date: Thu, 10 Jul 2025 17:19:28 +0100
Subject: [PATCH] openmp, fortran: Fix ICE when the procedure name cannot be
 found in declare variant directives [PR104428]

The result of searching for the procedure name symbol should be checked in
case the symbol cannot be found to avoid a null dereference.

gcc/fortran/

        PR fortran/104428
        * trans-openmp.cc (gfc_trans_omp_declare_variant): Check that proc_st
        is non-NULL before dereferencing.  Add line number to error message.

gcc/testsuite/

        PR fortran/104428
        * gfortran.dg/gomp/pr104428.f90: New.
---
 gcc/fortran/trans-openmp.cc                 |  5 +++--
 gcc/testsuite/gfortran.dg/gomp/pr104428.f90 | 16 ++++++++++++++++
 2 files changed, 19 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/pr104428.f90

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index f3d7cd4ffee..278e91c2c49 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -9714,11 +9714,12 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns, 
gfc_namespace *parent_ns)
        {
          gfc_symtree *proc_st;
          gfc_find_sym_tree (variant_proc_name, gfc_current_ns, 1, &proc_st);
-         variant_proc_sym = proc_st->n.sym;
+         variant_proc_sym = proc_st ? proc_st->n.sym : NULL;
        }
       if (variant_proc_sym == NULL)
        {
-         gfc_error ("Cannot find symbol %qs", variant_proc_name);
+         gfc_error ("Cannot find symbol %qs at %L", variant_proc_name,
+                                                    &odv->where);
          continue;
        }
       set_selectors = omp_check_context_selector
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr104428.f90 
b/gcc/testsuite/gfortran.dg/gomp/pr104428.f90
new file mode 100644
index 00000000000..a09e8853a1d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr104428.f90
@@ -0,0 +1,16 @@
+! { dg-do compile }
+! { dg-options "-fopenmp" }
+
+program p
+  interface
+    subroutine x
+    end subroutine x
+  end interface
+contains
+  subroutine foo
+    !$omp declare variant(x) match(construct={do})
+  end
+  subroutine bar
+    !$omp declare variant(y) match(construct={do}) ! { dg-error "Cannot find 
symbol .y." }
+  end
+end
-- 
2.43.0

Reply via email to