Created attachment 26872 [details] erroneous code causing GFortran to crash GFortran casts an internal error with the simple attached code using some new OO features of Fortran: # gfortran oo_err.f90 f951: internal compiler error: Speicherzugriffsfehler Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. The code is obviously erroneous; the bug is that GFortran crashes instead of giving graful explanations. Note: GFortran does behave if you omit "te::" in the allocate statement.
Invalid read of size 8 at 0x52A709: gfc_compare_derived_types(gfc_symbol*, gfc_symbol*) (interface.c:402) by 0x5943F6: gfc_type_is_extension_of(gfc_symbol*, gfc_symbol*) (symbol.c:4824) by 0x54DE3D: gfc_match_allocate() (match.c:3538)
More details: For gfc_match_allocate (match.c), one has: 3538 if (!gfc_type_compatible (&tail->expr->ts, &ts)) and then in gfc_type_compatible: (gdb) p ts1->type $6 = BT_CLASS (gdb) p ts2->type $7 = BT_DERIVED (gdb) p ts1->u.derived->components $10 = (gfc_component *) 0x16da1f0 (gdb) p ts1->u.derived->components->ts.u.derived $12 = (gfc_symbol *) 0x0 Which is used for: 4848 if (is_class1 && is_derived2) 4849 return gfc_type_is_extension_of(ts1->u.derived->components->ts.u.derived, 4850 ts2->u.derived); Due to the lacking ALLOCATE, tail->expr->ts.u.derived->attr.is_class == 1 Thus, one should check it. The question is only where: In gfc_match_allocate or in gfc_type_compatible?
(In reply to comment #2) > Due to the lacking ALLOCATE, > tail->expr->ts.u.derived->attr.is_class == 1 I wanted to say that "is_class" is not set (i.e. the expression above is false).
I think one can avoid the whole problem by reshuffling the order of checks being done in 'gfc_match_allocate', like this: Index: gcc/fortran/match.c =================================================================== --- gcc/fortran/match.c (revision 188139) +++ gcc/fortran/match.c (working copy) @@ -3533,6 +3533,28 @@ gfc_match_allocate (void) } } + /* FIXME: disable the checking on derived types and arrays. */ + sym = tail->expr->symtree->n.sym; + b1 = !(tail->expr->ref + && (tail->expr->ref->type == REF_COMPONENT + || tail->expr->ref->type == REF_ARRAY)); + if (sym && sym->ts.type == BT_CLASS && sym->attr.class_ok) + b2 = !(CLASS_DATA (sym)->attr.allocatable + || CLASS_DATA (sym)->attr.class_pointer); + else + b2 = sym && !(sym->attr.allocatable || sym->attr.pointer + || sym->attr.proc_pointer); + b3 = sym && sym->ns && sym->ns->proc_name + && (sym->ns->proc_name->attr.allocatable + || sym->ns->proc_name->attr.pointer + || sym->ns->proc_name->attr.proc_pointer); + if (b1 && b2 && !b3) + { + gfc_error ("Allocate-object at %L is neither a nonprocedure pointer " + "nor an allocatable variable", &tail->expr->where); + goto cleanup; + } + /* The ALLOCATE statement had an optional typespec. Check the constraints. */ if (ts.type != BT_UNKNOWN) @@ -3558,28 +3580,6 @@ gfc_match_allocate (void) if (tail->expr->ts.type == BT_DERIVED) tail->expr->ts.u.derived = gfc_use_derived (tail->expr->ts.u.derived); - /* FIXME: disable the checking on derived types and arrays. */ - sym = tail->expr->symtree->n.sym; - b1 = !(tail->expr->ref - && (tail->expr->ref->type == REF_COMPONENT - || tail->expr->ref->type == REF_ARRAY)); - if (sym && sym->ts.type == BT_CLASS && sym->attr.class_ok) - b2 = !(CLASS_DATA (sym)->attr.allocatable - || CLASS_DATA (sym)->attr.class_pointer); - else - b2 = sym && !(sym->attr.allocatable || sym->attr.pointer - || sym->attr.proc_pointer); - b3 = sym && sym->ns && sym->ns->proc_name - && (sym->ns->proc_name->attr.allocatable - || sym->ns->proc_name->attr.pointer - || sym->ns->proc_name->attr.proc_pointer); - if (b1 && b2 && !b3) - { - gfc_error ("Allocate-object at %L is neither a nonprocedure pointer " - "nor an allocatable variable", &tail->expr->where); - goto cleanup; - } - if (gfc_peek_ascii_char () == '(' && !sym->attr.dimension) { gfc_error ("Shape specification for allocatable scalar at %C"); This patch avoids the segfault and correctly rejects the test case. I hope it does not introduce any other problems (I'll try it on the testsuite soon).
(In reply to comment #4) > This patch avoids the segfault and correctly rejects the test case. I hope it > does not introduce any other problems (I'll try it on the testsuite soon). It passes the testsuite without any failures.
Author: janus Date: Fri Jun 8 17:26:11 2012 New Revision: 188335 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=188335 Log: 2012-06-08 Janus Weil <janus@gcc.gnu.org> PR fortran/52552 * match.c (gfc_match_allocate): Modify order of checks. Change wording of error message. Remove FIXME note. * resolve.c (resolve_allocate_expr): Add a comment. 2012-06-08 Janus Weil <janus@gcc.gnu.org> PR fortran/52552 * gfortran.dg/allocate_alloc_opt_1.f90: Modified. * gfortran.dg/allocate_class_1.f90: Modified. * gfortran.dg/allocate_with_typespec_4.f90: Modified. * gfortran.dg/allocate_class_2.f90: New. Added: trunk/gcc/testsuite/gfortran.dg/allocate_class_2.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/match.c trunk/gcc/fortran/resolve.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90 trunk/gcc/testsuite/gfortran.dg/allocate_class_1.f90 trunk/gcc/testsuite/gfortran.dg/allocate_with_typespec_4.f90
Fixed with r188335. Closing. Thanks for the report!
Nice! Thanks for fixing!