Bug 113997 - Bogus 'Warning: Interface mismatch in global procedure' with C binding
Summary: Bogus 'Warning: Interface mismatch in global procedure' with C binding
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 14.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2024-02-19 16:37 UTC by Tobias Burnus
Modified: 2024-02-19 18:28 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2024-02-19 16:37:33 UTC
The following warning is bogus, unless
  -fno-leading-underscore
is used:

    8 |     subroutine foo_c(x) bind(C, name="foo")
      |                    1
Warning: Interface mismatch in global procedure 'foo_c' at (1): Type mismatch in argument 'x' (TYPE(c_ptr)/TYPE(*))

* * *

Because for
  'subroutine acc_attach()'
  'subroutine acc_attach_c(x) bind(C, name="acc_attach"')

(A) the global Fortran name 'acc_attach' differs from the local name 'acc_attach_c'

(B) the actual name (DECL_ASSEMBLER_NAME) differs: 'acc_attach_c' is 'acc_attach' but 'acc_attach' is 'acc_attach_c'.

* * *

! The C and Fortran interfaces are part of OpenACC 3.3
! An alternative implementation would be a C implementation using
! ISO_Fortran_binding.h.

subroutine acc_attach(x)
  use iso_c_binding, only : c_loc
  implicit none (external, type)

  type(*), dimension(..), target :: x

  interface
    subroutine acc_attach_c(x) bind(C, name="acc_attach")
      use iso_c_binding
      type(c_ptr) :: x
    end subroutine
  end interface

  call acc_attach_c(c_loc(x))
end
Comment 1 kargls 2024-02-19 17:34:59 UTC
Can you provide a complete minimum example?  It seems that your
description conflicts with Fortran 2023, 19.2 Global identifiers.

1   ... entities with binding labels ... are global entities of a program.
    ... The name of ... external procedure with no binding label ... is a global
    identifier.  ... A binding label of an entity of the program is a global
    identifier.


2  The global identifier of an entity shall not be the same as the global identifier
   of any other entity. Furthermore, a binding label shall not be the same as the
   global identifier of any other global entity, ignoring differences in case.
Comment 2 anlauf 2024-02-19 17:55:02 UTC
I think I've seen something similar in a different PR before, where there is
confusion of globally visible names for bind(c) procedures.  Need to look
them up.

Anyway, renaming the binding label, like

    subroutine acc_attach_c(x) bind(C, name="acc_attach_renamed")

makes the code compile.
Comment 3 Tobias Burnus 2024-02-19 18:13:47 UTC
> Anyway, renaming the binding label, like
>    subroutine acc_attach_c(x) bind(C, name="acc_attach_renamed")
> makes the code compile.

Well, the code *does* compile as it is only a warning.

* * *

I think the problem here is a bit that on the Fortran-user side ('acc_attach' vs. 'acc_attach_c') and on the assembler-level side ('acc_attach_' vs. 'acc_attach') everything is fine (except with -fno-underscore) but, admittedly, not from the Fortran lanaguage side.

(On the other hand, Fortran itself is perfectly happy with:
'subroutine foo' and 'subroutine bar() Bind(C, name='foo_')' but that will break with most Fortran compilers.)

Thus, the question is whether we (gfortran) want to do something here - or are happy with issuing the semi-correct/semi-bogus warning here.

* * *

And renaming "acc_attach_c" does not really help as 'acc_attach' with C binding does exist. In this case it exists as:
  https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libgomp/oacc-mem.c;hb=refs/heads/master#l944
and renaming would just add another wrapper around it.


However, an alternative is the following - which is (nearly) identical, except that GCC does some GFC-CFC and back conversations – independent whether implemented in C or in Fortran:

subroutine acc_attach(x) bind(C, name="acc_attach_")
  use iso_c_binding, only : c_loc
  implicit none (external, type)

  type(*), dimension(..), target :: x

  interface
    subroutine acc_attach_c(x) bind(C, name="acc_attach")
      use iso_c_binding
      type(c_ptr) :: x
    end subroutine
  end interface

  call acc_attach_c(c_loc(x))
end
Comment 4 anlauf 2024-02-19 18:19:11 UTC
(In reply to Tobias Burnus from comment #3)
> > Anyway, renaming the binding label, like
> >    subroutine acc_attach_c(x) bind(C, name="acc_attach_renamed")
> > makes the code compile.
> 
> Well, the code *does* compile as it is only a warning.

Right.  I had an implicit -pedantic flag set...

Well, one of the PRs I had in mind is pr107659.
Comment 5 anlauf 2024-02-19 18:28:58 UTC
(In reply to Tobias Burnus from comment #3)
> However, an alternative is the following - which is (nearly) identical,
> except that GCC does some GFC-CFC and back conversations – independent
> whether implemented in C or in Fortran:
> 
> subroutine acc_attach(x) bind(C, name="acc_attach_")
>   use iso_c_binding, only : c_loc
>   implicit none (external, type)
> 
>   type(*), dimension(..), target :: x
> 
>   interface
>     subroutine acc_attach_c(x) bind(C, name="acc_attach")
>       use iso_c_binding
>       type(c_ptr) :: x
>     end subroutine
>   end interface
> 
>   call acc_attach_c(c_loc(x))
> end

Why not:

subroutine acc_attach_f(x)

and "renaming" it via

interface acc_attach
  module procedure acc_attach_f
end

?