* [Patch, Fortran] PR 42051,43896: [OOP] ICE in gfc_conv_variable, at fortran/trans-expr.c:551 @ 2010-06-11 7:17 Janus Weil 2010-06-11 7:18 ` Paul Richard Thomas 0 siblings, 1 reply; 7+ messages in thread From: Janus Weil @ 2010-06-11 7:17 UTC (permalink / raw) To: gfortran, gcc-patches [-- Attachment #1: Type: text/plain, Size: 1093 bytes --] Hi all, here is an OOP patch by Paul, which I am taking up and posting here because a) it is simple b) it has been lying around for a while c) it fixes two bugs (both of which have been reported by real-world users. In fact they are duplicates.) d) Paul seems to have little time for gfortran lately :( e) I simply want to get this baby in finally :) [Btw, the original test case in PR 42051 still does not work, but this is apparently due to some other bug, possibly related or equal to PR 44064.] The patch has been regtested on x86_64-unknown-linux-gnu. Ok for trunk? Actually, since it's Paul's patch, I guess I could just approve it myself (I do indeed think it's fine). Therefore I'll just commit it tomorrow on behalf of Paul if no one objects by then. Cheers, Janus 2010-06-11 Paul Thomas <pault@gcc.gnu.org> PR fortran/42051 PR fortran/43896 * trans-expr.c (gfc_conv_derived_to_class): Handle array-valued functions with CLASS formal arguments. 2010-06-11 Paul Thomas <pault@gcc.gnu.org> PR fortran/42051 PR fortran/43896 * gfortran.dg/class_23.f03: New test. [-- Attachment #2: pr42051.diff --] [-- Type: application/octet-stream, Size: 659 bytes --] Index: gcc/fortran/trans-expr.c =================================================================== --- gcc/fortran/trans-expr.c (revision 160588) +++ gcc/fortran/trans-expr.c (working copy) @@ -2492,12 +2492,14 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_exp ss = gfc_walk_expr (e); if (ss == gfc_ss_terminator) { + parmse->ss = NULL; gfc_conv_expr_reference (parmse, e); tmp = fold_convert (TREE_TYPE (ctree), parmse->expr); gfc_add_modify (&parmse->pre, ctree, tmp); } else { + parmse->ss = ss; gfc_conv_expr (parmse, e); gfc_add_modify (&parmse->pre, ctree, parmse->expr); } [-- Attachment #3: class_23.f03 --] [-- Type: application/octet-stream, Size: 470 bytes --] ! { dg-do compile } ! ! PR 42051: [OOP] ICE on array-valued function with CLASS formal argument ! ! Original test case by Damian Rouson <damian@rouson.net> ! Modified by Janus Weil <janus@gcc.gnu.org> type grid end type contains function return_x(this) result(this_x) class(grid) :: this real ,dimension(1) :: this_x end function subroutine output() type(grid) :: mesh real ,dimension(1) :: x x = return_x(mesh) end subroutine end ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch, Fortran] PR 42051,43896: [OOP] ICE in gfc_conv_variable, at fortran/trans-expr.c:551 2010-06-11 7:17 [Patch, Fortran] PR 42051,43896: [OOP] ICE in gfc_conv_variable, at fortran/trans-expr.c:551 Janus Weil @ 2010-06-11 7:18 ` Paul Richard Thomas 2010-06-11 8:15 ` Paul Richard Thomas 0 siblings, 1 reply; 7+ messages in thread From: Paul Richard Thomas @ 2010-06-11 7:18 UTC (permalink / raw) To: Janus Weil; +Cc: gfortran, gcc-patches Janus, > b) it has been lying around for a while Indeed, I have been trying to get back to completing the incorporation of arrays.... > c) it fixes two bugs (both of which have been reported by real-world > users. In fact they are duplicates.) > d) Paul seems to have little time for gfortran lately :( ...but, as you say, I have little time for gfortran of late. > e) I simply want to get this baby in finally :) > > [Btw, the original test case in PR 42051 still does not work, but this > is apparently due to some other bug, possibly related or equal to PR > 44064.] > > The patch has been regtested on x86_64-unknown-linux-gnu. Ok for trunk? > > Actually, since it's Paul's patch, I guess I could just approve it > myself (I do indeed think it's fine). Therefore I'll just commit it > tomorrow on behalf of Paul if no one objects by then. I think that approach would be appropriate. Thanks Paul ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch, Fortran] PR 42051,43896: [OOP] ICE in gfc_conv_variable, at fortran/trans-expr.c:551 2010-06-11 7:18 ` Paul Richard Thomas @ 2010-06-11 8:15 ` Paul Richard Thomas 2010-06-11 15:42 ` Paul Richard Thomas 0 siblings, 1 reply; 7+ messages in thread From: Paul Richard Thomas @ 2010-06-11 8:15 UTC (permalink / raw) To: Janus Weil; +Cc: gfortran, gcc-patches [-- Attachment #1: Type: text/plain, Size: 1301 bytes --] Dear Janus, Please find attached a development of a fix for pr41539, which touches the same place as the patch that you have forwarded this morning. I seem to recall that it fixes PR42051 as well. I'll check at lunchtime. Cheers Paul >> b) it has been lying around for a while > > Indeed, I have been trying to get back to completing the incorporation > of arrays.... > >> c) it fixes two bugs (both of which have been reported by real-world >> users. In fact they are duplicates.) >> d) Paul seems to have little time for gfortran lately :( > > ...but, as you say, I have little time for gfortran of late. > >> e) I simply want to get this baby in finally :) >> >> [Btw, the original test case in PR 42051 still does not work, but this >> is apparently due to some other bug, possibly related or equal to PR >> 44064.] >> >> The patch has been regtested on x86_64-unknown-linux-gnu. Ok for trunk? >> >> Actually, since it's Paul's patch, I guess I could just approve it >> myself (I do indeed think it's fine). Therefore I'll just commit it >> tomorrow on behalf of Paul if no one objects by then. > > I think that approach would be appropriate. > > Thanks > > Paul > -- The knack of flying is learning how to throw yourself at the ground and miss. --Hitchhikers Guide to the Galaxy [-- Attachment #2: submit.diff --] [-- Type: text/x-patch, Size: 5831 bytes --] Index: gcc/fortran/interface.c =================================================================== --- gcc/fortran/interface.c (revision 157307) +++ gcc/fortran/interface.c (working copy) @@ -1447,6 +1447,23 @@ if (symbol_rank (formal) == actual->rank) return 1; + if (formal->ts.type == BT_CLASS) + { + int formal_rank; + formal_rank = formal->ts.u.derived->components->as + ? formal->ts.u.derived->components->as->rank : 0; + if (formal_rank == actual->rank) + return 1; + else + { + if (where) + gfc_error ("Rank mismatch in argument '%s' at %L (%d and %d)", + formal->name, &actual->where, formal_rank, + actual->rank); + return 0; + } + } + rank_check = where != NULL && !is_elemental && formal->as && (formal->as->type == AS_ASSUMED_SHAPE || formal->as->type == AS_DEFERRED) Index: gcc/fortran/match.c =================================================================== --- gcc/fortran/match.c (revision 157307) +++ gcc/fortran/match.c (working copy) @@ -2394,7 +2394,7 @@ gfc_match_allocate (void) { gfc_alloc *head, *tail; - gfc_expr *stat, *errmsg, *tmp, *source; + gfc_expr *stat, *errmsg, *tmp, *source, *e; gfc_typespec ts; gfc_symbol *sym; match m; @@ -2455,6 +2455,18 @@ goto cleanup; } + /* A class object's array reference changes the expression type to that + of the declared type. Change it back to the class type for allocate + expressions. */ + e = tail->expr; + if (e->symtree->n.sym->ts.type == BT_CLASS + && e->ts.type == BT_DERIVED + && e->ref && e->ref->type == REF_COMPONENT + && strcmp (e->ref->u.c.component->name, "$data") == 0 + && (!e->ref->next + || (e->ref->next->type == REF_ARRAY && !e->ref->next->next))) + e->ts = e->symtree->n.sym->ts; + /* The ALLOCATE statement had an optional typespec. Check the constraints. */ if (ts.type != BT_UNKNOWN) Index: gcc/fortran/primary.c =================================================================== --- gcc/fortran/primary.c (revision 157307) +++ gcc/fortran/primary.c (working copy) @@ -1738,7 +1738,7 @@ { char name[GFC_MAX_SYMBOL_LEN + 1]; gfc_ref *substring, *tail; - gfc_component *component; + gfc_component *component = NULL; gfc_symbol *sym = primary->symtree->n.sym; match m; bool unknown; @@ -1754,14 +1754,30 @@ || (sym->ts.type == BT_CLASS && sym->ts.u.derived->components->attr.dimension)) { + if (sym->ts.type == BT_CLASS && gfc_peek_ascii_char () == '(') + { + component = gfc_find_component (sym->ts.u.derived, "$data", + true, true); + tail = extend_ref (primary, tail); + tail->type = REF_COMPONENT; + tail->u.c.component = component; + tail->u.c.sym = sym; + } + /* In EQUIVALENCE, we don't know yet whether we are seeing an array, character variable or array of character variables. We'll leave the decision till resolve time. */ tail = extend_ref (primary, tail); tail->type = REF_ARRAY; - m = gfc_match_array_ref (&tail->u.ar, equiv_flag ? NULL : sym->as, - equiv_flag); + if (sym->ts.type == BT_CLASS) + m = gfc_match_array_ref (&tail->u.ar, equiv_flag ? NULL : + sym->ts.u.derived->components->as, + equiv_flag); + else + m = gfc_match_array_ref (&tail->u.ar, equiv_flag ? NULL : + sym->as, equiv_flag); + if (m != MATCH_YES) return m; @@ -1777,7 +1793,10 @@ } } - primary->ts = sym->ts; + if (sym->ts.type == BT_CLASS && component) + primary->ts = component->ts; + else + primary->ts = sym->ts; if (equiv_flag) return MATCH_YES; @@ -2757,7 +2776,8 @@ /* If the symbol has a dimension attribute, the expression is a variable. */ - if (sym->attr.dimension) + if (sym->attr.dimension + || (sym->ts.type == BT_CLASS && sym->ts.u.derived->components->attr.dimension)) { if (gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name, NULL) == FAILURE) Index: gcc/fortran/trans-expr.c =================================================================== --- gcc/fortran/trans-expr.c (revision 157307) +++ gcc/fortran/trans-expr.c (working copy) @@ -2596,14 +2596,28 @@ /* Set the vptr. */ cmp = gfc_find_component (declared, "$vptr", true, true); - ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl), - var, cmp->backend_decl, NULL_TREE); - /* Remember the vtab corresponds to the derived type - not to the class declared type. */ - vtab = gfc_find_derived_vtab (e->ts.u.derived); - gcc_assert (vtab); - tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab)); + /* Remember the vtab corresponds to the derived type not to the + class declared type, unless this is an array reference to a + class object. */ + if (((e->expr_type == EXPR_VARIABLE) || (e->expr_type == EXPR_FUNCTION)) + && e->symtree->n.sym->ts.type == BT_CLASS) + { + tmp = gfc_get_symbol_decl (e->symtree->n.sym); + ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl), + tmp, cmp->backend_decl, NULL_TREE); + tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl), + tmp, cmp->backend_decl, NULL_TREE); + } + else + { + ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl), + var, cmp->backend_decl, NULL_TREE); + vtab = gfc_find_derived_vtab (e->ts.u.derived); + gcc_assert (vtab); + tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab)); + } + gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp)); @@ -2620,7 +2634,7 @@ } else { - gfc_conv_expr (parmse, e); + gfc_conv_expr_descriptor (parmse, e, ss); gfc_add_modify (&parmse->pre, ctree, parmse->expr); } ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch, Fortran] PR 42051,43896: [OOP] ICE in gfc_conv_variable, at fortran/trans-expr.c:551 2010-06-11 8:15 ` Paul Richard Thomas @ 2010-06-11 15:42 ` Paul Richard Thomas 2010-06-11 17:48 ` Janus Weil 0 siblings, 1 reply; 7+ messages in thread From: Paul Richard Thomas @ 2010-06-11 15:42 UTC (permalink / raw) To: Janus Weil; +Cc: gfortran, gcc-patches [-- Attachment #1: Type: text/plain, Size: 426 bytes --] Please find attached an updated version of the patch that I sent this morning. It applies to revision 159428. It fixes pr41539, pr42051_1.f90 and pr43896.f90, up to defined operators for classes. I was in the midst of tackling pr41951, when I ground to a halt. I'll take a further look at it over the weekend. (Janus, feel free to commit the posted patch. I will modify this one to suit - thanks, by the way :-) ) Paul [-- Attachment #2: submit.diff --] [-- Type: text/x-patch, Size: 5714 bytes --] Index: gcc/fortran/interface.c =================================================================== --- gcc/fortran/interface.c (revision 159428) +++ gcc/fortran/interface.c (working copy) @@ -1507,6 +1507,23 @@ if (symbol_rank (formal) == actual->rank) return 1; + if (formal->ts.type == BT_CLASS) + { + int formal_rank; + formal_rank = formal->ts.u.derived->components->as + ? formal->ts.u.derived->components->as->rank : 0; + if (formal_rank == actual->rank) + return 1; + else + { + if (where) + gfc_error ("Rank mismatch in argument '%s' at %L (%d and %d)", + formal->name, &actual->where, formal_rank, + actual->rank); + return 0; + } + } + rank_check = where != NULL && !is_elemental && formal->as && (formal->as->type == AS_ASSUMED_SHAPE || formal->as->type == AS_DEFERRED) Index: gcc/fortran/trans-expr.c =================================================================== --- gcc/fortran/trans-expr.c (revision 159428) +++ gcc/fortran/trans-expr.c (working copy) @@ -2479,15 +2479,28 @@ /* Set the vptr. */ cmp = gfc_find_component (declared, "$vptr", true, true); - ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl), - var, cmp->backend_decl, NULL_TREE); + + /* Remember the vtab corresponds to the derived type not to the + class declared type, unless this is an array reference to a + class object. */ + if (((e->expr_type == EXPR_VARIABLE) || (e->expr_type == EXPR_FUNCTION)) + && e->symtree->n.sym->ts.type == BT_CLASS) + { + tmp = gfc_get_symbol_decl (e->symtree->n.sym); + ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl), + tmp, cmp->backend_decl, NULL_TREE); + tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl), + tmp, cmp->backend_decl, NULL_TREE); + } + else + { + ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl), + var, cmp->backend_decl, NULL_TREE); + vtab = gfc_find_derived_vtab (e->ts.u.derived, true); + gcc_assert (vtab); + tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab)); + } - /* Remember the vtab corresponds to the derived type - not to the class declared type. */ - vtab = gfc_find_derived_vtab (e->ts.u.derived, true); - gcc_assert (vtab); - gfc_trans_assign_vtab_procs (&parmse->pre, e->ts.u.derived, vtab); - tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab)); gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp)); @@ -2498,13 +2511,15 @@ ss = gfc_walk_expr (e); if (ss == gfc_ss_terminator) { + parmse->ss = NULL; gfc_conv_expr_reference (parmse, e); tmp = fold_convert (TREE_TYPE (ctree), parmse->expr); gfc_add_modify (&parmse->pre, ctree, tmp); } else { - gfc_conv_expr (parmse, e); + parmse->ss = ss; + gfc_conv_expr_descriptor (parmse, e, ss); gfc_add_modify (&parmse->pre, ctree, parmse->expr); } Index: gcc/fortran/match.c =================================================================== --- gcc/fortran/match.c (revision 159428) +++ gcc/fortran/match.c (working copy) @@ -2679,7 +2679,7 @@ gfc_match_allocate (void) { gfc_alloc *head, *tail; - gfc_expr *stat, *errmsg, *tmp, *source; + gfc_expr *stat, *errmsg, *tmp, *source, *e; gfc_typespec ts; gfc_symbol *sym; match m; @@ -2740,6 +2740,18 @@ goto cleanup; } + /* A class object's array reference changes the expression type to that + of the declared type. Change it back to the class type for allocate + expressions. */ + e = tail->expr; + if (e->symtree->n.sym->ts.type == BT_CLASS + && e->ts.type == BT_DERIVED + && e->ref && e->ref->type == REF_COMPONENT + && strcmp (e->ref->u.c.component->name, "$data") == 0 + && (!e->ref->next + || (e->ref->next->type == REF_ARRAY && !e->ref->next->next))) + e->ts = e->symtree->n.sym->ts; + /* The ALLOCATE statement had an optional typespec. Check the constraints. */ if (ts.type != BT_UNKNOWN) Index: gcc/fortran/primary.c =================================================================== --- gcc/fortran/primary.c (revision 159428) +++ gcc/fortran/primary.c (working copy) @@ -1725,7 +1725,7 @@ { char name[GFC_MAX_SYMBOL_LEN + 1]; gfc_ref *substring, *tail; - gfc_component *component; + gfc_component *component = NULL; gfc_symbol *sym = primary->symtree->n.sym; match m; bool unknown; @@ -1759,6 +1759,16 @@ || (sym->ts.type == BT_CLASS && sym->ts.u.derived->components->attr.dimension)) { + if (sym->ts.type == BT_CLASS && gfc_peek_ascii_char () == '(') + { + component = gfc_find_component (sym->ts.u.derived, "$data", + true, true); + tail = extend_ref (primary, tail); + tail->type = REF_COMPONENT; + tail->u.c.component = component; + tail->u.c.sym = sym; + } + /* In EQUIVALENCE, we don't know yet whether we are seeing an array, character variable or array of character variables. We'll leave the decision till resolve time. */ @@ -1782,7 +1792,10 @@ } } - primary->ts = sym->ts; + if (sym->ts.type == BT_CLASS && component) + primary->ts = component->ts; + else + primary->ts = sym->ts; if (equiv_flag) return MATCH_YES; @@ -2765,7 +2778,8 @@ /* If the symbol has a dimension attribute, the expression is a variable. */ - if (sym->attr.dimension) + if (sym->attr.dimension + || (sym->ts.type == BT_CLASS && sym->ts.u.derived->components->attr.dimension)) { if (gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name, NULL) == FAILURE) ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch, Fortran] PR 42051,43896: [OOP] ICE in gfc_conv_variable, at fortran/trans-expr.c:551 2010-06-11 15:42 ` Paul Richard Thomas @ 2010-06-11 17:48 ` Janus Weil 0 siblings, 0 replies; 7+ messages in thread From: Janus Weil @ 2010-06-11 17:48 UTC (permalink / raw) To: Paul Richard Thomas; +Cc: gfortran, gcc-patches > (Janus, feel free to commit the posted patch. I will modify this one > to suit - thanks, by the way :-) ) Did that (r160622). Thanks, Janus ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch, Fortran] PR 42051,43896: [OOP] ICE in gfc_conv_variable, at fortran/trans-expr.c:551 @ 2010-06-11 19:25 Dominique Dhumieres 0 siblings, 0 replies; 7+ messages in thread From: Dominique Dhumieres @ 2010-06-11 19:25 UTC (permalink / raw) To: fortran; +Cc: gcc-patches, janus, paul.richard.thomas Paul, Your patch in http://gcc.gnu.org/ml/fortran/2010-06/msg00112.html breaks the tests for pr44465 while fixing various problems: several ICEs for tests in pr41951 disappear, but are replaced with questionable errors, others give 'Internal Error at (1)', e.g. a test for pr42888, now the first test in pr42051 compiles and links along with some others (no more errors "Undefined symbols: "_vtab$..."). Dominique ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch, Fortran] PR 42051,43896: [OOP] ICE in gfc_conv_variable, at fortran/trans-expr.c:551 @ 2010-06-11 22:05 Dominique Dhumieres 0 siblings, 0 replies; 7+ messages in thread From: Dominique Dhumieres @ 2010-06-11 22:05 UTC (permalink / raw) To: fortran; +Cc: gcc-patches, janus, paul.richard.thomas With the patch in http://gcc.gnu.org/ml/fortran/2010-06/msg00112.html I have the following failures in the test suite: [macbook] f90/bug% gfc /opt/gcc/work/gcc/testsuite/gfortran.dg/allocate_derived_1.f90 /opt/gcc/work/gcc/testsuite/gfortran.dg/allocate_derived_1.f90:35.12: ... end 1 Internal Error at (1): find_array_spec(): Component not found and [macbook] f90/bug% gfc -O /opt/gcc/work/gcc/testsuite/gfortran.dg/dynamic_dispatch_4.f03 /opt/gcc/work/gcc/testsuite/gfortran.dg/dynamic_dispatch_4.f03: In function 'getit': /opt/gcc/work/gcc/testsuite/gfortran.dg/dynamic_dispatch_4.f03:79:0: error: statement makes a memory store, but has no VDEFS a_3.$vptr = D.1778_2; /opt/gcc/work/gcc/testsuite/gfortran.dg/dynamic_dispatch_4.f03:79:0: internal compiler error: verify_ssa failed Dominique ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-06-11 21:42 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-06-11 7:17 [Patch, Fortran] PR 42051,43896: [OOP] ICE in gfc_conv_variable, at fortran/trans-expr.c:551 Janus Weil 2010-06-11 7:18 ` Paul Richard Thomas 2010-06-11 8:15 ` Paul Richard Thomas 2010-06-11 15:42 ` Paul Richard Thomas 2010-06-11 17:48 ` Janus Weil 2010-06-11 19:25 Dominique Dhumieres 2010-06-11 22:05 Dominique Dhumieres
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).