Bug 52552 - [OOP] ICE when trying to allocate non-allocatable object giving a dynamic type
[OOP] ICE when trying to allocate non-allocatable object giving a dynamic type
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.4.6
: P3 normal
: ---
Assigned To: janus
: ice-on-invalid-code
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-03-10 14:58 UTC by gccbgz.lionm
Modified: 2012-06-08 18:56 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-03-10 00:00:00


Attachments
erroneous code causing GFortran to crash (148 bytes, text/plain)
2012-03-10 14:58 UTC, gccbgz.lionm
Details

Note You need to log in before you can comment on or make changes to this bug.
Description gccbgz.lionm 2012-03-10 14:58:25 UTC
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.
Comment 1 Tobias Burnus 2012-03-10 19:10:10 UTC
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)
Comment 2 Tobias Burnus 2012-03-12 11:24:23 UTC
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?
Comment 3 Tobias Burnus 2012-03-12 11:29:25 UTC
(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).
Comment 4 janus 2012-06-07 16:25:57 UTC
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).
Comment 5 janus 2012-06-08 07:55:34 UTC
(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.
Comment 6 janus 2012-06-08 17:26:18 UTC
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
Comment 7 janus 2012-06-08 17:38:46 UTC
Fixed with r188335. Closing.

Thanks for the report!
Comment 8 gccbgz.lionm 2012-06-08 18:56:19 UTC
Nice! Thanks for fixing!