There are interoperability issues with integer :: single_variable COMMON /name/ single_variable and C. Currently, gfortran generates the equivalent to struct { int single_variable } however - at least with BIND(C) - it should be compatible to int single_variable That's what bind_c_coms.f90/bind_c_coms_driver.c test and which is failing with -flto on the LTO branch. See Fortran 2003, "15.3 Interoperation with C global variables": "A C variable with external linkage interoperates with a common block that has been specified in a BIND statement (1) if the C variable is of a struct type and the variables that are members of the common block are interoperable with corresponding components of the struct type, or (2) if the common block contains a single variable, and the variable is interoperable with the C variable." * * * Next question: What should happen without BIND(C)? Answer: In F2003, "5.5.2.4 Differences between named common and blank common" one finds: "A blank common block has the same properties as a named common block, except for the following: [...] (2) Named common blocks of the same name shall be of the same size in all scoping units of a program in which they appear, but blank common blocks may be of different sizes." By construction, blank common names are not accessible from C. Thus from the standard, one could do the "struct"-less version for named commons and the "struct" version for blank commons. I do not know whether there are compatibility issues with old programs; however, the general advice was to use "struct". * * * I think one should drop some kind of note in the Release Notes and add a few words about COMMON to http://gcc.gnu.org/onlinedocs/gfortran/Mixed_002dLanguage-Programming.html Another huge issue is padding: In C one has - by default - padding, in Fortran (according to the language standard) not. gfortran uses padding (cf. -fno-align-commons), however. One probably should exclude the BIND(C) COMMONS from the -fno-align-commons option and should check that C does exactly the same padding. See also PR 41209 for a means to set, e.g., the padding.
In any case gcc/dwarf2out.c needs to be modified. It currently has: fortran_common (tree decl, HOST_WIDE_INT *value) { [...] if (TREE_CODE (val_expr) != COMPONENT_REF) return NULL_TREE; However, one needs to create a DW_TAG_common_block which contains a DW_TAG_variable.
The way usually recommended is to use a struct for interoperability with Fortran common blocks, say http://support.microsoft.com/kb/51614 Unfortunately, the idiom "use a single variable common block, say common/x/y, access it via the name of the common block, followed by an underscore, say x_" is also common. At least in my workplace it's the way everybody uses. In other words, we can't afford to break either way.
I have now asked at comp.lang.fortran: http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/c00efc5679b6a879 (In reply to comment #2) > The way usually recommended is to use a struct for interoperability with > Fortran common blocks, say http://support.microsoft.com/kb/51614 That matches - for multiple variables in the block - the Fortran 2003 standard. > Unfortunately, the idiom "use a single variable common block, say common/x/y, > access it via the name of the common block, followed by an underscore, say x_" > is also common. At least in my workplace it's the way everybody uses. That matches what Fortran 2003 says about a single variable. > In other words, we can't afford to break either way. Well, as long as you do not use LTO it does not seem to matter. And if LTO you have to decide for "struct" or against "struct". (And as a user, use BIND(C) - either with COMMON or with TYPE - and you get a well-defined result.) I am leaning towards using a "struct" only when there are multiple variables, which makes BIND(C) and non-BIND(C) behave identical. If the overwhelming opinion is differently, one can still add a "&& attr->is_bind_c".
Test case: gfortran -flto bind_c_coms_driver.c bind_c_coms.f90
Also asked at: http://gcc.gnu.org/ml/fortran/2010-02/msg00010.html a) The derived-type issue (cf. PR 41664) is now fixed. b) Regarding COMMON w/ single item in the named COMMON (F2003, 15.3); unclear whether it is supposed to interoperate with both the single C variable and the struct or only with the former. I have now asked at http://j3-fortran.org/pipermail/j3/2010-February/
Regarding my question, Toon ask this question to Bill Long @ Cray and Jim Xia @ IBM at the Las Vegas meeting of J3/WG5 - they came to different conclusions ;-) Bill Long stated what he also wrote at http://j3-fortran.org/pipermail/j3/2010-February/003358.html Namely: The "OR" is to be read as exclusive "OR": > > Does a common block containing a single variable (e.g. of type > > "integer(c_int)") need to be interoperable with the C variable ("int") > > only [i.e. only (2)] > > Yes, this is my interpretation. Toon agreed more with Bill and commented: "I think this is due to the fact that - as every 'vendor' knows - the C compiler being the 'companion processor' (C interoperability terminology) to its Fortran processor, it can allow additional interoperability (for instance, allow COMMON /blah/ I interoperate with struct {int i;} blah;)." Thus, from the standard in a three-to-two-reading*, one only needs to interoperate with the single variable and not with the struct. (* My reading, Toon's, Bill's vs. Nick's (fortran@gcc) and Jim's.) -- Note: I have not submitted an official interpretation request, for which all J3/WG5 members have to vote. I really wonder whether supporting both in LTO would be the better option compared with changing it to a single variable in the frontend.
Subject: Re: COMMON block, BIND(C) and LTO interoperability issues On Tue, 23 Feb 2010, burnus at gcc dot gnu dot org wrote: > ------- Comment #6 from burnus at gcc dot gnu dot org 2010-02-23 09:08 ------- > Regarding my question, Toon ask this question to Bill Long @ Cray and Jim Xia @ > IBM at the Las Vegas meeting of J3/WG5 - they came to different conclusions ;-) > > Bill Long stated what he also wrote at > http://j3-fortran.org/pipermail/j3/2010-February/003358.html > > Namely: The "OR" is to be read as exclusive "OR": > > > Does a common block containing a single variable (e.g. of type > > > "integer(c_int)") need to be interoperable with the C variable ("int") > > > only [i.e. only (2)] > > > > Yes, this is my interpretation. > > Toon agreed more with Bill and commented: "I think this is due to the fact that > - as every 'vendor' knows - the C compiler being the 'companion processor' (C > interoperability terminology) to its Fortran processor, it can allow additional > interoperability (for instance, allow COMMON /blah/ I interoperate with struct > {int i;} blah;)." > > Thus, from the standard in a three-to-two-reading*, one only needs to > interoperate with the single variable and not with the struct. (* My reading, > Toon's, Bill's vs. Nick's (fortran@gcc) and Jim's.) -- Note: I have not > submitted an official interpretation request, for which all J3/WG5 members have > to vote. > > I really wonder whether supporting both in LTO would be the better option > compared with changing it to a single variable in the frontend. That's certainly possible (though possibly not trivial - in fact part of it is already implemented, as in LTO doesn't complain about this inter-operation but later the optimizers might break things if you do not build with -fno-strict-aliasing). Richard.
Mine. See http://gcc.gnu.org/ml/gcc-patches/2010-05/msg02424.html for an outline for a possible fix.
This is still not fixed (at least by design - bind_c_coms.f90/bind_c_coms_driver.c passes with -flto now). Can somebody produce a reduced testcase pair that just has a bind-C named common with a single int so I can experiment a bit? Thx.
(In reply to Richard Biener from comment #9) > Can somebody produce a reduced testcase pair that > just has a bind-C named common with a single int so I can experiment a bit? $ cat s.f90 module foo use iso_c_binding integer(c_int) :: i common /com/ i bind(c,name="toto") :: /com/ end module foo $ cat s.c int main(void) { extern int toto; toto = 42; }
I think there is no good way apart from treating single-element structs equal to its single element in LTO with regarding to TYPE_CANONICAL. At least not if you want to inter-operate with both int i; and struct { int i; }. Otherwise I'd lean towards not using a struct in Fortran for single-element commons. That should be an implementation detail anyways. > Unfortunately, the idiom "use a single variable common block, say common/x/y, > access it via the name of the common block, followed by an underscore, say x_" > is also common. At least in my workplace it's the way everybody uses. But then simply name the symbol of the variable without a struct in that way, no?
I disagree with Tobias' reading: it seems to me that the single-variable common block should be interoperable with both the single-common C struct and C variable. The Intel compiler makes both cases work: [fx@kelvin tmp]$ cat a.f90 program test use iso_c_binding integer(c_int) :: i common /a/ i bind(c) :: /a/ interface subroutine foo() bind(c) end subroutine end interface i = 42 print *, i call foo() print *, i end program test [fx@kelvin tmp]$ cat a1.c extern int a; void foo (void) { a = -1; } [fx@kelvin tmp]$ cat a2.c extern struct { int i; } a; void foo (void) { a.i = -1; } [fx@kelvin tmp]$ icc -c a1.c && ifort a.f90 a1.o && ./a.out 42 -1 [fx@kelvin tmp]$ icc -c a2.c && ifort a.f90 a2.o && ./a.out 42 -1 I believe we should do so too. And if I understand correctly what Richard said, this means relaxing the LTO type rules, is that right?
On Mon, 14 Jul 2014, fxcoudert at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41227 > > --- Comment #12 from Francois-Xavier Coudert <fxcoudert at gcc dot gnu.org> --- > I disagree with Tobias' reading: it seems to me that the single-variable common > block should be interoperable with both the single-common C struct and C > variable. > > The Intel compiler makes both cases work: > > [fx@kelvin tmp]$ cat a.f90 > program test > use iso_c_binding > integer(c_int) :: i > common /a/ i > bind(c) :: /a/ > > interface > subroutine foo() bind(c) > end subroutine > end interface > > i = 42 > print *, i > call foo() > print *, i > end program test > [fx@kelvin tmp]$ cat a1.c > extern int a; > void foo (void) { a = -1; } > [fx@kelvin tmp]$ cat a2.c > extern struct { int i; } a; > void foo (void) { a.i = -1; } > [fx@kelvin tmp]$ icc -c a1.c && ifort a.f90 a1.o && ./a.out > 42 > -1 > [fx@kelvin tmp]$ icc -c a2.c && ifort a.f90 a2.o && ./a.out > 42 > -1 > > > I believe we should do so too. And if I understand correctly what Richard said, > this means relaxing the LTO type rules, is that right? Yes (to get rid of the warning and to avoid eventual wrong-code bugs). Does it need to inter-operate with extern struct { struct { int i; } a; } a; ? Or extern union { int i; } a; ?
(In reply to rguenther@suse.de from comment #13) > Does it need to inter-operate with > extern struct { struct { int i; } a; } a; No, I don't read anything in the standard that would allow this. > extern union { int i; } a; No, per F2008 15.3.4 ¶3: "There is no Fortran type that is interoperable with a C union type."
Ok, the warning is implemented with checking gimple type compatibility in lto/lto-symtab.c: if (!types_compatible_p (TREE_TYPE (prevailing->decl), TREE_TYPE (decl))) diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0, "type of %qD does not match original " "declaration", decl); I'm not sure it is wise to drop the outermost single-element struct type from all types during compute of canonical types. We can adjust gimple_get_alias_set to at least assign the same alias sets to such struct and its element, but that doesn't cure the warning (obviously). At least that avoids generating wrong code... like with @@ -2307,6 +2308,27 @@ gimple_get_alias_set (tree t) || t == unsigned_char_type_node) return 0; + /* For C, Fortran interoperability assign the same alias-set to + a record with a single element as that element. */ + if (TREE_CODE (t) == RECORD_TYPE) + { + tree f = NULL_TREE; + for (tree fld = TYPE_FIELDS (t); fld != NULL_TREE; fld = TREE_CHAIN (fld)) + { + if (TREE_CODE (fld) != FIELD_DECL) + continue; + if (f == NULL_TREE) + f = fld; + else + { + f = NULL_TREE; + break; + } + } + if (f) + return get_alias_set (TREE_TYPE (f)); + } + /* Allow aliasing between signed and unsigned variants of the same but I'm sure we don't want to call get_alias_set on all globals during WPA phase (Where the warning is emitted). Humm. We can special-case that case in lto-symtab.c of course. Btw, what kind of single-elements can I expect? I suppose they can be arbitrary (so aggregate as well)?
(In reply to Richard Biener from comment #15) > Btw, what kind of single-elements can I expect? I suppose they can > be arbitrary (so aggregate as well)? From the Fortran/C interop side, we can get anything that is itself C/Fortran interoperable. So that is POD of various types (integers, floating-points and complexes, bool and char), pointer types, structs of those and arrays.
(In reply to Francois-Xavier Coudert from comment #12) > I disagree with Tobias' reading: it seems to me that the single-variable > common block should be interoperable with both the single-common C struct > and C variable. Well, Bill Long of Cray seems to agree with my interpretation, cf. http://mailman.j3-fortran.org/pipermail/j3/2010-February/003358.html > The Intel compiler makes both cases work: Well, it also works with gfortran - the question is only whether it works by chance or by purpose. If it works by chance and is invalid LTO is not required to support it.
(In reply to Francois-Xavier Coudert from comment #14) > (In reply to rguenther@suse.de from comment #13) > > Does it need to inter-operate with > > extern struct { struct { int i; } a; } a; > No, I don't read anything in the standard that would allow this. By your argument, int i; and struct { int i; } a; are interoperable. By this argument, one can also claim that it applies to struct { struct { int i; } a; } a; At least I fail to see a difference between the single and the nested struct. Otherwise, I stand to what I wrote before: I think the standard does not demand the interoperability. There are surely programs out there which do assume for a scalar variable in a common block that it interoperates with "int" and others which assume that it interoperates with "struct { int i; }". Thus, one might decide that one wants to support both versions with LTO. But one shouldn't do so by arguing with the Fortran standard.
On Mon, 14 Jul 2014, burnus at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41227 > > --- Comment #17 from Tobias Burnus <burnus at gcc dot gnu.org> --- > (In reply to Francois-Xavier Coudert from comment #12) > > I disagree with Tobias' reading: it seems to me that the single-variable > > common block should be interoperable with both the single-common C struct > > and C variable. > > Well, Bill Long of Cray seems to agree with my interpretation, cf. > http://mailman.j3-fortran.org/pipermail/j3/2010-February/003358.html But that answer suggests we get it wrong (currenty interoperating with the C struct { int i; } works and with the plain decl it doesn't). The answer specifically doesn't say that only (1) is valid. > > The Intel compiler makes both cases work: > > Well, it also works with gfortran - the question is only whether it works by > chance or by purpose. If it works by chance and is invalid LTO is not required > to support it. Currently it works "by chance" because without LTO the compiler doesn't see both sides. With LTO it notices there is an inconsistency that with a clever testcase will result in wrong code (make a fortran subroutine that assigns sth to the variable, call it from the C main after its assignment of 42, read the var again in main and see it optimized to '42' in case the fortran function call is inlined)
Let's please not invent new semantics. There are two things to distinguish: 1) legacy code, where no interoperability semantics were defined 2) new code, where the semantics are defined I don't know much about 2), but I do know that the recommendation back in the days was that a common block is represented by a struct, and everybody knew that the layout of a struct with a single variable is the same as for the variable itself. I don't think anybody was silly enough to nest structs around their variable. Unfortunately, this is still not entirely simple. Fortran allows accessing the same memory by different names which may have different types: what do you do with INTEGER A, B, C COMMON /D/ E(3) REAL E EQUIVALENCE (E(1),A), (E(2),B), (E(3),C) ? Or, to make things even more annoying DOUBLE PRECISON X INTEGER I(2) EQUIVALENCE (X, I(1)) COMMON /annoying/ X ? There's one more problem: Fortran's TYPE, the equivalent of the struct {}, was defined in Fortran 90 -- before the interoperability stuff. So the question is what to do with common block that contain a single TYPE variable. Until I started writing this, I tought "well, just allow this struct vs. single variable only for single-valued, scalar contents of the common block", but my second example showed me that this wouldn't work -- after all is the common content scalar (one double) or array-valued (two ints)? Now, since we're talking about legacy stuff and we don't want to invent new language rules, I think we can restrict ourselves to supporting the simplest case: a single INTEGER, REAL or DOUBLE PRECISION ignoring possible EQUIVALENCES, but I don't know if this is easily achieved on the LTO side. Going further is not worth it, it's not like there are heaps of bug reports about this problem.
(In reply to Tobias Burnus from comment #18) > By your argument, > int i; > and > struct { int i; } a; > are interoperable. No. The standard only defines interoperability as a one-to-one mapping between one Fortran entity and one C entity. An "extern int i" and "integer(int_c) :: i" are interoperable. By the standard, a common block with i as single variable is interoperable with "extern struct { int i; } a;" or "int i;" (where the question is whether "or" is exclusive or not). But I don't see how you can expand that to mean that the common block is interoperable with "struct { struct { int i; } a; } a;" by a simple reading of the standard. There are, in my reading, 2 or 3 (with the same "or" as before) entities interoperable with this nested struct: - a derived type containing a derived type containing "integer(int_c) :: i" - a common containing the dt containing the dt - a common containing a derived type containing "integer(int_c) :: i" > Otherwise, I stand to what I wrote before: I think the standard does not > demand the interoperability. Let's raise a formal interp, then.
(In reply to rguenther@suse.de from comment #19) > > Well, Bill Long of Cray seems to agree with my interpretation, cf. > > http://mailman.j3-fortran.org/pipermail/j3/2010-February/003358.html > > But that answer suggests we get it wrong (currenty interoperating > with the C struct { int i; } works and with the plain decl it > doesn't). The answer specifically doesn't say that only (1) > is valid. As I stumbled over it again (and missed what I wrote 5 years ago in comment 0): One also needs to distinguish between common blocks with and without BIND(C). The Fortran standard only defines interoperability with C with Fortran 2003's C binding ("BIND(C)"). Thus, "external int i" interoperates with use iso_fortran_env, only: c_int integer(c_int) :: j common /i/ j bind(C) :: /i/ and for this construct, "struct {int i}" does not have to interoperate with it according to the standard. If the front-end produces the wrong code in this case, one can simply fix it. Seems as if we have to do this, including the output DWARF. [By the way, I assume that there is essentially no code out there, which uses BIND(C) with COMMON: Either it is pre-Fortran-2003 code - or it uses modules where one avoids all those issues with COMMON and either has "integer, bind(C) :: i" or "type(t), bind(C) :: i" and no ambiguity.] The other case is legacy code: There, programs can make the wildest assumptions what C code should interoperable with Fortran. See also T.S.'s comment 20. Seems as if a simple "struct" was the most common assumption - with a nonstruct being effectively interoperable with a one-variable struct; hence, also the latter seems to be used.
OK, I got here from discussion at https://gcc.gnu.org/ml/gcc-patches/2015-05/msg02577.html because I am trying to get the canonical type calculation to the more standard compliant shape. My reading of the standard is that the variable in question should be interoperable with int, not struct {int}, because I do not see any derived type in Fortran source. In that case it would be nice to make gfortran to just drop the struct for BIND(C) types if possible. Making this work on LTO level probably means to peel off single element struct/aggregate. Other variant is to simply punt those types to alias set 0. So in this case I would agree with Tobias, Comment #22, but this is my first even attempt to make sense of Fortran standard. As for legacy code, perhaps gfortran can propagate BIND(C) to middle-end (i.e. add type attribute "bind_c" to those types) and we could add a warning when fortran declaration of type !bind_c gets merged with non-fortran declaration in lto-symtab and hopefully help people to annotate their source codes.
I'm not working on this. The comment#12 testcase shows the diagnostic happening but it works at runtime because we a) honor "must-alias" for QOI reasons and the accesses are not enough obfuscated (and I don't know how to obfuscate on the fortran side). Adjusted testcase: program test use iso_c_binding integer(c_int) :: i integer :: j common /a/ i bind(c) :: /a/ interface subroutine foo() bind(c) end subroutine end interface i = 42 call foo() j = i print *, j end program test --- extern int a; void foo (void) { a = -1; } where we end up with __MEM <int> (&a) = _Literal (int) -1; j = _Literal (int) -1; with -O -fno-tree-fre -fno-tree-dominator-opts we see __MEM <int> (&a) = _Literal (int) -1; _1 = a.i; j = _1; but clearly this way around is even valid when taking the struct as prevailing and using the component as access type. So I think we should be safe?