Error Cannot Change Attributes Of Use-associated Symbol At 1
User account creation filtered due to spam. Bug57141 - Cannot change attributes of USE-associated intrinsic Summary: Cannot change attributes of USE-associated intrinsic Status: RESOLVED FIXED Alias: None Product: gcc Classification: Unclassified Component: fortran (show other bugs) Version: unknown Importance: P3 normal Target Milestone: --- Assignee: Not yet assigned to anyone URL: Keywords: rejects-valid Depends on: Blocks: Reported: 2013-05-02 08:13 UTC by Roger Ferrer Ibanez Modified: 2013-05-05 14:05 UTC (History) CC List: 1 user (show) burnus See Also: Host: Target: Build: Known to work: Known to fail: 4.1.2, 4.3.4, 4.5.3, 4.6.3, 4.7.3, 4.8.0, 4.9.0 Last reconfirmed: 2013-05-02 00:00:00 Attachments Add an attachment (proposed patch, testcase, etc.) Note You need to log in before you can comment on or make changes to this bug. Description Roger Ferrer Ibanez 2013-05-02 08:13:34 UTC Hi, gfortran-4.8 (and 4.7 as well and possibly earlier versions too) complain with this snippet. The error message is not emitted if the declaration of R is uncommented. ! -- test.f90 MODULE M INTRINSIC :: NULL !! Uncommenting the following statement !! causes the error go away ! REAL, POINTER :: R(:) => NULL() END MODULE M MODULE M_INTERN USE M IMPLICIT NONE REAL, POINTER :: ARR(:) => NULL() END MODULE M_INTERN ! -- end of test.f90 $ gfortran -c test.f90 test.f90:12.37: REAL, POINTER :: ARR(:) => NULL() 1 Error: Cannot change attributes of USE-associated symbol null at (1) Kind regards, Comment 1 Dominique d'Humieres 2013-05-02 11:13:01 UTC Confirmed from 4.3.1 to trunk. Comment 2 Tobias Burnus 2013-05-03 08:59:48 UTC decl.c's gfc_match_null has: gfc_intrinsic_symbol (sym); if (sym->attr.proc != PROC_INTRINSIC && (!gfc_add_procedure(&sym->attr, PROC_INTRINSIC, sym->name, NULL) || !gfc_add_function (&sym->attr, sym->name, NULL))) return MATCH_ERROR; Failing is the call to gfc_add_procedure. Here, attr.proc = PROC_UNKNOWN attr.intrinsic = 1 attr.use_assoc = 1 attr.if_source = IFSRC_DECL Possible patch? --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -1705,2 +1705,3 @@ gfc_match_null (gfc_expr **result) if (sym->attr.proc != PROC_INTRINSIC + && !(sym->attr.use_assoc && sym->attr.intrinsic) && (!gfc_add_procedure(&sym->attr, PROC_INTRINSIC, sym->name, NULL) Comment 3 Tobias Burnus 2013-05-05 14:04:42 UTC Author: burnus Date: Sun May 5 14:01:38 2013 New Revision: 198609 URL: http://gcc.gnu.org/viewcvs?rev=198609&root=gcc&view=rev Log: 2013-05-05 Tobias Burnus by: [ date ] [ thread ] [ subject ] [ author ] Thank you Stephan, it is working now. I forgot to add the correct files to the makefile, for I put the module in a seperate file (grid.F). The correct makefile rule for the main program (main.F) is: main: grid.o main.o chkopts -${FLINKER} -o main grid.o main.o ${PETSC_KSP_LIB} ${RM} main.o grid.o Thanks again. Leo 2010/10/1 Stephan Kramer which reproduces the trouble : MODULE a USE iso_c_binding INTERFACE SUBROUTINE foo1(a) BIND(C,name="a_c_routine") IMPORT C_INT INTEGER(C_INT) ::a END SUBROUTINE END INTERFACE END MODULE MODULE b http://coding.derkeiler.com/Archive/Fortran/comp.lang.fortran/2007-08/msg00877.html USE a,ONLY : foo1 INTERFACE foo MODULE procedure foo1,foo2,foo3 END INTERFACE CONTAINS SUBROUTINE foo2(a) DOUBLE PRECISION ::a END SUBROUTINE SUBROUTINE foo3(a) CHARACTER ::a END SUBROUTINE END MODULE [lcoul@b04p0004 test]$ http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html g95 -c test2.f90 In file test2.f90:13 MODULE procedure foo1,foo2,foo3 1 Error: Cannot change attributes of USE-associated symbol 'foo1' at (1) Ah. Now that I think I can help error cannot with. The error message is a little confusing (though not so much so as the paraphrasing that talked about changing host association), but I think the critical bit here is that foo1 is *NOT* a module procedure. Yes, I know that you accessed it via a USE statement, but that doesn't make it a module procedure. It is error cannot change an external procedure whose interface happens to be defined in a module. So I don't think this is a compiler bug, other than perhaps insomuch as the error message could be better. There is a bit of "silliness" in the f95 module procedure statement. Mostly the whole business about restricting it to module procedures is what seems silly to me. I don't think that restriction was well thought out. It isn't as though the restriction achieves anything useful. I think the writers just overlooked the fact that it could be useful for procedures other than module ones. There are several things that are really awkward because of this restriction. (Notably, it is hard to put a single external procedure in two different generics; I'm not even sure there is a workaround to that one.) The silliness was fixed in f2003. I don't recall whether Andy yet implemented the f2003 form of this statement in g95. In f2003, you just omit the keyword "module" and it no longer has the silly can share your pain. Topics These "gotchas" are nasty because they will not fail on some machines, while failing on others (given various combinations of compilers and machine platforms). Danger with Optional Arguments Danger with intent(out) A suprise with non-advancing I/O Suprise with locally initialized variables Danger of calling Fortran 90 style routines Danger with interfaces to Fortran 77 subroutines A suprise with generic functions Big Danger with Undefined Pointers Subtle danger with overloading (=) to assign pointers Danger with pointers to pointers Danger with Optional Arguments In this example an optional argument is used to determine if a header is printed. subroutine print_char(this,header) character(len=*), intent (in) :: this logical, optional, intent (in) :: header ! THIS IS THE WRONG WAY if (present(header) .and. header) then print *, 'This is the header ' endif print *, this end subroutine print_char subroutine print_char(this,header) character(len=*), intent (in) :: this logical, optional, intent (in) :: header ! THIS IS THE RIGHT WAY if (present(header)) then if (header) print *, 'This is the header ' endif print *, this end subroutine print_char Explanation The first method is not safe because the compiler is allowed to evaluate the header argument before the present function is evaluated. If the header argument is not in fact present an out of bounds memory reference could occur, which could cause a failure. Danger with intent(out) In this example we assign components of a derived type with intent(out). program intent_gotcha type mytype integer :: x real :: y end type mytype type (mytype) :: a a%x = 1 ; a%y = 2. call assign(a) ! a%y COULD BE UNDEFINED HERE print *, a contains subroutine assign(this) type (mytype), intent (out) :: this ! THIS IS THE WRONG WAY this%x = 2 end subroutine assign subroutine assign(this) type (mytype), intent (out) :: this ! THIS IS THE RIGHT WAY this%x = 2 ; this%y = 2. end subroutine assign end program intent_gotcha Explanation The problem is that when intent(out) is used with a derived type, any component not assigned in a procedure could become undefined on exit. For example, even though a%y was defined on entry to this routine, it could become undefined on exit because it was never assigned within t