http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51904

Tobias Burnus <burnus at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |ice-on-valid-code
                 CC|                            |burnus at gcc dot gnu.org
      Known to work|                            |4.1.2, 4.3.4, 4.4.0, 4.5.3
   Target Milestone|---                         |4.6.3
            Summary|Internal Compiler Error on  |[4.6/4.7 Regression] ICE on
                   |size function evaluation    |SIZE function evaluation
      Known to fail|                            |4.6.3, 4.7.0

--- Comment #1 from Tobias Burnus <burnus at gcc dot gnu.org> 2012-01-19 
16:25:54 UTC ---
 Invalid read of size 8
    at 0x57C267: resolve_code(gfc_code*, gfc_namespace*) (resolve.c:8316)
    by 0x57DE2B: gfc_resolve_blocks(gfc_code*, gfc_namespace*) (resolve.c:9038)
    by 0x5819B5: resolve_code(gfc_code*, gfc_namespace*) (resolve.c:9307)
    by 0x58412E: resolve_codes(gfc_namespace*) (resolve.c:13931)

That's:
resolve_transfer (gfc_code *code)
{
...
  if (exp == NULL || (exp->expr_type != EXPR_VARIABLE
                      && exp->expr_type != EXPR_FUNCTION))
    return;
...
  sym = exp->symtree->n.sym; /* <<< segfault */

The problem is that:
(gdb) p exp->symtree
$5 = (gfc_symtree *) 0x0
(gdb) p exp->value.function
$6 = {actual = 0x15fc710, name = 0xf5939f "size", isym = 0x162c0e8, esym = 0x0}


The program works with pathf95, g95, NAG f95 and gfortran 4.1 to 4.5, but
segfaults with 4.6 and 4.7

 * * *

I tried the following patch [only the first part is needed] - but it fails then
later at

  Invalid read of size 8
    at 0x5D3E91: gfc_conv_expr_reference(gfc_se*, gfc_expr*)
(trans-expr.c:5510)
    by 0x5F2686: gfc_trans_transfer(gfc_code*) (trans-io.c:2306)
    by 0x5A4987: trans_code(gfc_code*, tree_node*) (trans.c:1522)
    by 0x5F01E9: build_dt(tree_node*, gfc_code*) (trans-io.c:1832)
    by 0x5A49A7: trans_code(gfc_code*, tree_node*) (trans.c:1494)
    by 0x5CAA8A: gfc_generate_function_code(gfc_namespace*) (trans-decl.c:5329)

There, the issue is:

  if (expr->expr_type == EXPR_FUNCTION
      && ((expr->value.function.esym ....
          || (!expr->value.function.esym
              && expr->symtree->n.sym->attr.pointer

Namely: If "esym" does not exist, the code assumes that the symtree is
available - but in this case one has only an "isym".

I have somehow the feeling that the error must be up-chain.

--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -8303,4 +8303,5 @@ resolve_transfer (gfc_code *code)

-  if (exp == NULL || (exp->expr_type != EXPR_VARIABLE
-                     && exp->expr_type != EXPR_FUNCTION))
+  if (exp == NULL
+      || (exp->expr_type != EXPR_VARIABLE && exp->expr_type != EXPR_FUNCTION)
+      || (exp->expr_type == EXPR_FUNCTION && exp->value.function.isym))
     return;
@@ -8315,3 +8316,4 @@ resolve_transfer (gfc_code *code)

-  sym = exp->symtree->n.sym;
+  sym = exp->expr_type == EXPR_FUNCTION && exp->value.function.esym
+       ? exp->value.function.esym : exp->symtree->n.sym;
   ts = &sym->ts;

Reply via email to