Summary: | [OOP] Polymorphic class fails at runtime | ||
---|---|---|---|
Product: | gcc | Reporter: | Prince <jilfa12> |
Component: | fortran | Assignee: | Tobias Burnus <burnus> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | burnus, janus |
Priority: | P3 | Keywords: | rejects-valid |
Version: | 4.7.0 | ||
Target Milestone: | 4.7.0 | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2012-01-25 00:00:00 | |
Attachments: | A factory pattern design to illustrate class pointers (polymorphic) behavior |
Description
Prince
2012-01-25 10:28:14 UTC
I confirm that on x86_64-apple-darwin10 from gcc version 4.6.0 20100723 (experimental) [trunk revision 162456] (GCC) up to now, gfortran gives the following errors for the test pr51995.f90:91.31: CALL db_connect%description() 1 Error: 'description' at (1) is not a member of the 'connection' structure pr51995.f90:98.31: CALL db_connect%description() 1 Error: 'description' at (1) is not a member of the 'connection' structure while up to gcc version 4.6.0 20100413 (experimental) [trunk revision 158252] (GCC) it gives pr51995.f90:15.28: PROCEDURE(generic_desc), DEFERRED, PASS(self) :: description 1 Error: Passed-object dummy argument of 'generic_desc' at (1) must not be POINTER pr51995.f90:82.23: USE factory_pattern 1 Fatal Error: Can't open module file 'factory_pattern.mod' for reading at (1): No such file or directory Also gcc version 4.6.0 20100506 (experimental) [trunk revision 159106] (GCC) gives f951: internal compiler error: in find_typebound_proc_uop, at fortran/symbol.c:5255 Please submit a full bug report, So if it has worked, it looks like a transient. Using today's GCC 4.7 and using one one-week-old one, it compiles without any error. It seems as if the bug has been already fixed - or it only affects certain architectures. Can you provide more details about the used GCC version ("gfortran -v")? You should also try a newer version and check whether the issue still occurs. (In reply to comment #1) > I confirm that on x86_64-apple-darwin10 from > gcc version 4.6.0 20100723 (experimental) [trunk revision 162456] (GCC) up to > now, gfortran gives the following errors Hmm, it also works for me (on x86_64-unknown-linux-gnu) with 4.6.3 20111212 [gcc-4_6-branch revision 182222] 4.6.3 20120121 [gcc-4_6-branch revision 183121] I tried running gfortran through valgrind (4.7 and 4.6) but that only shows memory leakage. As it does not fail for me, I cannot debug it, sorry. Thanks Dominiq. I tested the program on i686 GNU/Linux running on Ubuntu-Maverick using gcc version 4.7.0 20120118 (experimental) (GCC). Using ifort 12, it gives the correct results. So it is definitely a bug in gfortran. Do you have any work-around? ________________________________ From: dominiq at lps dot ens.fr <gcc-bugzilla@gcc.gnu.org> To: jilfa12@yahoo.com Sent: Wednesday, January 25, 2012 12:59 PM Subject: [Bug fortran/51995] Polymorphic class fails at runtime http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51995 --- Comment #1 from Dominique d'Humieres <dominiq at lps dot ens.fr> 2012-01-25 10:59:09 UTC --- I confirm that on x86_64-apple-darwin10 from gcc version 4.6.0 20100723 (experimental) [trunk revision 162456] (GCC) up to now, gfortran gives the following errors for the test pr51995.f90:91.31: CALL db_connect%description() 1 Error: 'description' at (1) is not a member of the 'connection' structure pr51995.f90:98.31: CALL db_connect%description() 1 Error: 'description' at (1) is not a member of the 'connection' structure while up to gcc version 4.6.0 20100413 (experimental) [trunk revision 158252] (GCC) it gives pr51995.f90:15.28: PROCEDURE(generic_desc), DEFERRED, PASS(self) :: description 1 Error: Passed-object dummy argument of 'generic_desc' at (1) must not be POINTER pr51995.f90:82.23: USE factory_pattern 1 Fatal Error: Can't open module file 'factory_pattern.mod' for reading at (1): No such file or directory Also gcc version 4.6.0 20100506 (experimental) [trunk revision 159106] (GCC) gives f951: internal compiler error: in find_typebound_proc_uop, at fortran/symbol.c:5255 Please submit a full bug report, So if it has worked, it looks like a transient. Ignore that. I missed that one needs *both* the attachment and the program. Thus, I can actually reproduce it. Sorry for the pilot error. Thus, I am able to reproduce it both with 4.5, 4.6 and 4.7. (The program compiles with ifort 12.1 - and at a glance, I cannot spot anything which looks invalid.) Thanks for the prompt reply. I tested the program on i686 GNU/Linux running on Ubuntu-Maverick using gcc version 4.7.0 20120118 (experimental) (GCC). ________________________________ From: burnus at gcc dot gnu.org <gcc-bugzilla@gcc.gnu.org> To: jilfa12@yahoo.com Sent: Wednesday, January 25, 2012 1:05 PM Subject: [Bug fortran/51995] Polymorphic class fails at runtime http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51995 --- Comment #2 from Tobias Burnus <burnus at gcc dot gnu.org> 2012-01-25 11:05:41 UTC --- Using today's GCC 4.7 and using one one-week-old one, it compiles without any error. It seems as if the bug has been already fixed - or it only affects certain architectures. Can you provide more details about the used GCC version ("gfortran -v")? You should also try a newer version and check whether the issue still occurs. The problem seems to be the following: One properly calls match_typebound_call, which sets "base" (alias "primary") to the symtree of "db_connect" (which is of type BT_CLASS). Then it calls: gfc_match_varspec (primary=0x16cf3d0, equiv_flag=0, sub_flag=true, ppc_arg=true) There, the problem is that one has: sym = sym->ts.u.derived; if (sym->f2k_derived) But "sym" is only the class container. One needs sym->components->ts.u.derived->f2k_derived. One could simply do: --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -1911 +1911,2 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, - sym = sym->ts.u.derived; + sym = (sym->ts.type == BT_CLASS) ? CLASS_DATA (sym)->ts.u.derived + : sym->ts.u.derived; But that will fail later with internal compiler error: in gfc_conv_component_ref, at fortran/trans-expr.c:1100 (In reply to comment #4) > I tested the program on i686 GNU/Linux running on Ubuntu-Maverick using gcc > version 4.7.0 20120118 (experimental) (GCC). > > So it is definitely a bug in gfortran. Do you have any work-around? Unfortunately, I am not aware of a workaround. I have to admit that I have not fully understood why fclass->f2k_derived gets often but not always set. However, the following patch works. Thus, you could either apply it and build your own GCC, or you wait a day after the committal and get a nightly build at http://gcc.gnu.org/wiki/GFortranBinaries - or you convince Matthias to do a new Ubuntu build. (In reply to comment #7) > There, the problem is that one has: > sym = sym->ts.u.derived; > if (sym->f2k_derived) Actually, f2k_derived should also get set for the class container. Better patch (read: actually working) patch: --- a/gcc/fortran/class.c +++ b/gcc/fortran/class.c @@ -421,6 +421,8 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr, c->attr.access = ACCESS_PRIVATE; c->attr.pointer = 1; } + else if (!fclass->f2k_derived) + fclass->f2k_derived = fclass->components->ts.u.derived->f2k_derived; /* Since the extension field is 8 bit wide, we can only have up to 255 extension levels. */ Using five days old gcc version 4.7.0 20120120 (experimental) (GCC), the problem still persists. I think the problem has not been fixed for the i686 architecture. Do you know of any work-around for this? Ifort 12.1 runs the program successfully without memory leak. ________________________________ From: burnus at gcc dot gnu.org <gcc-bugzilla@gcc.gnu.org> To: jilfa12@yahoo.com Sent: Wednesday, January 25, 2012 2:47 PM Subject: [Bug fortran/51995] [OOP] Polymorphic class fails at runtime http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51995 --- Comment #7 from Tobias Burnus <burnus at gcc dot gnu.org> 2012-01-25 12:47:49 UTC --- The problem seems to be the following: One properly calls match_typebound_call, which sets "base" (alias "primary") to the symtree of "db_connect" (which is of type BT_CLASS). Then it calls: gfc_match_varspec (primary=0x16cf3d0, equiv_flag=0, sub_flag=true, ppc_arg=true) There, the problem is that one has: sym = sym->ts.u.derived; if (sym->f2k_derived) But "sym" is only the class container. One needs sym->components->ts.u.derived->f2k_derived. One could simply do: --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -1911 +1911,2 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, - sym = sym->ts.u.derived; + sym = (sym->ts.type == BT_CLASS) ? CLASS_DATA (sym)->ts.u.derived + : sym->ts.u.derived; But that will fail later with internal compiler error: in gfc_conv_component_ref, at fortran/trans-expr.c:1100 Author: burnus Date: Wed Jan 25 17:34:39 2012 New Revision: 183528 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=183528 Log: 2012-01-25 Tobias Burnus <burnus@net-b.de> PR fortran/51995 * class.c (gfc_build_class_symbol): Ensure that fclass->f2k_derived is set. 2012-01-25 Tobias Burnus <burnus@net-b.de> PR fortran/51995 * gfortran.dg/typebound_proc_25.f90: New. Added: trunk/gcc/testsuite/gfortran.dg/typebound_proc_25.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/class.c trunk/gcc/testsuite/ChangeLog FIXED on the trunk (4.7). Thanks for the bug report! See comment 8 for how to obtain a newer version. On x86_64-apple-darwin10 and an almost clean tree (i.e., with only the patch for pr 51985) at revision 183528, compiling testsuite/gfortran.dg/typebound_proc_25.f90 gives an ICE: [macbook] f90/bug% gfcp /opt/gcc/work/gcc/testsuite/gfortran.dg/typebound_proc_25.f90 /opt/gcc/work/gcc/testsuite/gfortran.dg/typebound_proc_25.f90:88:0: internal compiler error: in gfc_release_symbol, at fortran/symbol.c:2531 instead of the errors (the same happens on my main patched tree). Reduced test case exhibiting the ICE: MODULE factory_pattern TYPE CFactory PRIVATE CHARACTER(len=20) :: factory_type !! Descriptive name for database CLASS(Connection), POINTER :: connection_type !! Which type of database ? CONTAINS !! Note 'class' not 'type' ! PROCEDURE :: create_connection !! Connect to database END TYPE CFactory TYPE, ABSTRACT :: Connection CONTAINS PROCEDURE(generic_desc), DEFERRED, PASS(self) :: description END TYPE Connection ABSTRACT INTERFACE SUBROUTINE generic_desc(self) IMPORT :: Connection CLASS(Connection), INTENT(in) :: self END SUBROUTINE generic_desc END INTERFACE !! An Oracle connection TYPE, EXTENDS(Connection) :: OracleConnection CONTAINS PROCEDURE, PASS(self) :: description => oracle_desc END TYPE OracleConnection CONTAINS FUNCTION create_connection(self) RESULT(ptr) CLASS(CFactory) :: self CLASS(Connection), POINTER :: ptr END FUNCTION create_connection SUBROUTINE oracle_desc(self) CLASS(OracleConnection), INTENT(in) :: self END SUBROUTINE oracle_desc END MODULE factory_pattern Author: burnus Date: Wed Jan 25 22:21:14 2012 New Revision: 183541 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=183541 Log: 2012-01-25 Tobias Burnus <burnus@net-b.de> PR fortran/51995 * class.c (gfc_build_class_symbol): Fix invalid freeing issue with fclass->f2k_derived. Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/class.c |