Patchwork [Fortran,comitted] PR56969 - Fix bogus ambiguous symbol error for ISO_C_Binding intrinsics

login
register
mail settings
Submitter Tobias Burnus
Date April 16, 2013, 2:17 p.m.
Message ID <516D5D82.3000206@net-b.de>
Download mbox | patch
Permalink /patch/236977/
State New
Headers show

Comments

Tobias Burnus - April 16, 2013, 2:17 p.m.
The problem was that C_ASSOCIATED was made available multiple times. As 
gfc_intrinsic_func_interface calls gfc_intrinsic_symbol, the sym->module 
was set to "(intrinsic)" which didn't match the original 
"__iso_c_binding". Hence, the symbols weren't recognized as the same and 
an error is printed.

I have commit the attached patch as obvious, after a successful built 
and regtesting on x86-64-gnu-linux.
Rev. 198000.

Tobias

Patch

2013-04-16  Tobias Burnus  <burnus@net-b.de>

	PR fortran/56969
	* intrinsic.c (gfc_intrinsic_func_interface): Don't set
	module name to "(intrinsic)" for intrinsics from intrinsic
	modules.

2013-04-16  Tobias Burnus  <burnus@net-b.de>

	PR fortran/56969
	* gfortran.dg/c_assoc_5.f90: New.

diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index c431279..688332f 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -4236,7 +4236,8 @@  gfc_intrinsic_func_interface (gfc_expr *expr, int error_flag)
 
 got_specific:
   expr->value.function.isym = specific;
-  gfc_intrinsic_symbol (expr->symtree->n.sym);
+  if (!expr->symtree->n.sym->module)
+    gfc_intrinsic_symbol (expr->symtree->n.sym);
 
   if (!error_flag)
     gfc_pop_suppress_errors ();
--- /dev/null	2013-04-16 09:37:35.264983505 +0200
+++ gcc/gcc/testsuite/gfortran.dg/c_assoc_5.f90	2013-04-16 13:31:04.335893680 +0200
@@ -0,0 +1,69 @@ 
+! { dg-do compile }
+!
+! PR fortran/56969
+!
+! Contributed by Salvatore Filippone
+!
+! Was before rejected as the different c_associated weren't recognized to
+! come from the same module.
+!
+module test_mod
+  use iso_c_binding 
+
+  type(c_ptr), save :: test_context = c_null_ptr
+
+  type, bind(c) :: s_Cmat
+    type(c_ptr) :: Mat = c_null_ptr
+  end type s_Cmat
+
+  
+  interface 
+    function FtestCreate(context) &
+         & bind(c,name="FtestCreate") result(res)
+      use iso_c_binding
+      type(c_ptr)    :: context
+      integer(c_int) :: res
+    end function FtestCreate
+  end interface
+contains
+  
+  function initFtest() result(res)
+    implicit none 
+    integer(c_int) :: res
+    if (c_associated(test_context)) then 
+      res = 0
+    else
+      res = FtestCreate(test_context)
+    end if
+  end function initFtest
+end module test_mod
+
+module base_mat_mod
+  type base_sparse_mat
+    integer, allocatable :: ia(:)
+  end type base_sparse_mat
+end module base_mat_mod
+
+module extd_mat_mod
+
+  use iso_c_binding
+  use test_mod
+  use base_mat_mod
+
+  type, extends(base_sparse_mat) :: extd_sparse_mat
+    type(s_Cmat) :: deviceMat
+  end type extd_sparse_mat
+
+end module extd_mat_mod
+
+subroutine extd_foo(a) 
+
+  use extd_mat_mod
+  implicit none 
+  class(extd_sparse_mat), intent(inout) :: a
+
+  if (c_associated(a%deviceMat%Mat)) then 
+    write(*,*) 'C Associated'
+  end if
+
+end subroutine extd_foo