OSDN Git Service

2009-07-09 Janus Weil <janus@gcc.gnu.org>
authorjanus <janus@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Jul 2009 14:07:03 +0000 (14:07 +0000)
committerjanus <janus@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Jul 2009 14:07:03 +0000 (14:07 +0000)
PR fortran/40646
* dump-parse-tree.c (show_expr): Renamed 'is_proc_ptr_comp'.
* expr.c (is_proc_ptr_comp): Renamed to 'gfc_is_proc_ptr_comp'.
(gfc_check_pointer_assign): Renamed 'is_proc_ptr_comp'.
(replace_comp,gfc_expr_replace_comp): New functions, analogous
to 'replace_symbol' and 'gfc_expr_replace_symbol', just with components
instead of symbols.
* gfortran.h (gfc_expr_replace_comp): New prototype.
(is_proc_ptr_comp): Renamed to 'gfc_is_proc_ptr_comp'.
* interface.c (compare_actual_formal): Renamed 'is_proc_ptr_comp'.
* match.c (gfc_match_pointer_assignment): Ditto.
* primary.c (gfc_match_varspec): Handle array-valued procedure pointers
and procedure pointer components. Renamed 'is_proc_ptr_comp'.
* resolve.c (resolve_fl_derived): Correctly handle interfaces with
RESULT statement, and handle array-valued procedure pointer components.
(resolve_actual_arglist,resolve_ppc_call,resolve_expr_ppc): Renamed
'is_proc_ptr_comp'.
* trans-array.c (gfc_walk_function_expr): Ditto.
* trans-decl.c (gfc_get_symbol_decl): Security check for presence of
ns->proc_name.
* trans-expr.c (gfc_conv_procedure_call): Handle array-valued procedure
pointer components. Renamed 'is_proc_ptr_comp'.
(conv_function_val,gfc_trans_arrayfunc_assign): Renamed
'is_proc_ptr_comp'.
(gfc_get_proc_ptr_comp): Do not modify the argument 'e', but instead
make a copy of it.
* trans-io.c (gfc_trans_transfer): Handle array-valued procedure
pointer components.

2009-07-09  Janus Weil  <janus@gcc.gnu.org>

PR fortran/40646
* gfortran.dg/proc_ptr_22.f90: New.
* gfortran.dg/proc_ptr_comp_12.f90: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149419 138bc75d-0d04-0410-961f-82ee72b054a4

15 files changed:
gcc/fortran/ChangeLog
gcc/fortran/dump-parse-tree.c
gcc/fortran/expr.c
gcc/fortran/gfortran.h
gcc/fortran/interface.c
gcc/fortran/match.c
gcc/fortran/primary.c
gcc/fortran/resolve.c
gcc/fortran/trans-array.c
gcc/fortran/trans-decl.c
gcc/fortran/trans-expr.c
gcc/fortran/trans-io.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/proc_ptr_22.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/proc_ptr_comp_12.f90 [new file with mode: 0644]

index 3f3feec..ceabd60 100644 (file)
@@ -1,3 +1,34 @@
+2009-07-09  Janus Weil  <janus@gcc.gnu.org>
+
+       PR fortran/40646
+       * dump-parse-tree.c (show_expr): Renamed 'is_proc_ptr_comp'.
+       * expr.c (is_proc_ptr_comp): Renamed to 'gfc_is_proc_ptr_comp'.
+       (gfc_check_pointer_assign): Renamed 'is_proc_ptr_comp'.
+       (replace_comp,gfc_expr_replace_comp): New functions, analogous
+       to 'replace_symbol' and 'gfc_expr_replace_symbol', just with components
+       instead of symbols.
+       * gfortran.h (gfc_expr_replace_comp): New prototype.
+       (is_proc_ptr_comp): Renamed to 'gfc_is_proc_ptr_comp'.
+       * interface.c (compare_actual_formal): Renamed 'is_proc_ptr_comp'.
+       * match.c (gfc_match_pointer_assignment): Ditto.
+       * primary.c (gfc_match_varspec): Handle array-valued procedure pointers
+       and procedure pointer components. Renamed 'is_proc_ptr_comp'.
+       * resolve.c (resolve_fl_derived): Correctly handle interfaces with
+       RESULT statement, and handle array-valued procedure pointer components.
+       (resolve_actual_arglist,resolve_ppc_call,resolve_expr_ppc): Renamed
+       'is_proc_ptr_comp'.
+       * trans-array.c (gfc_walk_function_expr): Ditto.
+       * trans-decl.c (gfc_get_symbol_decl): Security check for presence of
+       ns->proc_name.
+       * trans-expr.c (gfc_conv_procedure_call): Handle array-valued procedure
+       pointer components. Renamed 'is_proc_ptr_comp'.
+       (conv_function_val,gfc_trans_arrayfunc_assign): Renamed
+       'is_proc_ptr_comp'.
+       (gfc_get_proc_ptr_comp): Do not modify the argument 'e', but instead
+       make a copy of it.
+       * trans-io.c (gfc_trans_transfer): Handle array-valued procedure
+       pointer components.
+
 2009-07-09  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/40604
index cfd8a7d..2a411d4 100644 (file)
@@ -544,7 +544,7 @@ show_expr (gfc_expr *p)
       if (p->value.function.name == NULL)
        {
          fprintf (dumpfile, "%s", p->symtree->n.sym->name);
-         if (is_proc_ptr_comp (p, NULL))
+         if (gfc_is_proc_ptr_comp (p, NULL))
            show_ref (p->ref);
          fputc ('[', dumpfile);
          show_actual_arglist (p->value.function.actual);
@@ -553,7 +553,7 @@ show_expr (gfc_expr *p)
       else
        {
          fprintf (dumpfile, "%s", p->value.function.name);
-         if (is_proc_ptr_comp (p, NULL))
+         if (gfc_is_proc_ptr_comp (p, NULL))
            show_ref (p->ref);
          fputc ('[', dumpfile);
          fputc ('[', dumpfile);
index b1d572e..a8f9f6a 100644 (file)
@@ -3213,7 +3213,7 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
        }
 
       /* TODO: Enable interface check for PPCs.  */
-      if (is_proc_ptr_comp (rvalue, NULL))
+      if (gfc_is_proc_ptr_comp (rvalue, NULL))
        return SUCCESS;
       if ((rvalue->expr_type == EXPR_VARIABLE
           && !gfc_compare_interfaces (lvalue->symtree->n.sym,
@@ -3558,7 +3558,7 @@ gfc_expr_set_symbols_referenced (gfc_expr *expr)
    provided).  */
 
 bool
-is_proc_ptr_comp (gfc_expr *expr, gfc_component **comp)
+gfc_is_proc_ptr_comp (gfc_expr *expr, gfc_component **comp)
 {
   gfc_ref *ref;
   bool ppc = false;
@@ -3672,3 +3672,39 @@ gfc_expr_replace_symbols (gfc_expr *expr, gfc_symbol *dest)
 {
   gfc_traverse_expr (expr, dest, &replace_symbol, 0);
 }
+
+/* The following is analogous to 'replace_symbol', and needed for copying
+   interfaces for procedure pointer components. The argument 'sym' must formally
+   be a gfc_symbol, so that the function can be passed to gfc_traverse_expr.
+   However, it gets actually passed a gfc_component (i.e. the procedure pointer
+   component in whose formal_ns the arguments have to be).  */
+
+static bool
+replace_comp (gfc_expr *expr, gfc_symbol *sym, int *i ATTRIBUTE_UNUSED)
+{
+  gfc_component *comp;
+  comp = (gfc_component *)sym;
+  if ((expr->expr_type == EXPR_VARIABLE 
+       || (expr->expr_type == EXPR_FUNCTION
+          && !gfc_is_intrinsic (expr->symtree->n.sym, 0, expr->where)))
+      && expr->symtree->n.sym->ns == comp->ts.interface->formal_ns)
+    {
+      gfc_symtree *stree;
+      gfc_namespace *ns = comp->formal_ns;
+      /* Don't use gfc_get_symtree as we prefer to fail badly if we don't find
+        the symtree rather than create a new one (and probably fail later).  */
+      stree = gfc_find_symtree (ns ? ns->sym_root : gfc_current_ns->sym_root,
+                               expr->symtree->n.sym->name);
+      gcc_assert (stree);
+      stree->n.sym->attr = expr->symtree->n.sym->attr;
+      expr->symtree = stree;
+    }
+  return false;
+}
+
+void
+gfc_expr_replace_comp (gfc_expr *expr, gfc_component *dest)
+{
+  gfc_traverse_expr (expr, (gfc_symbol *)dest, &replace_comp, 0);
+}
+
index 260d718..5e3f80f 100644 (file)
@@ -2539,8 +2539,9 @@ bool gfc_traverse_expr (gfc_expr *, gfc_symbol *,
 void gfc_expr_set_symbols_referenced (gfc_expr *);
 gfc_try gfc_expr_check_typed (gfc_expr*, gfc_namespace*, bool);
 void gfc_expr_replace_symbols (gfc_expr *, gfc_symbol *);
+void gfc_expr_replace_comp (gfc_expr *, gfc_component *);
 
-bool is_proc_ptr_comp (gfc_expr *, gfc_component **);
+bool gfc_is_proc_ptr_comp (gfc_expr *, gfc_component **);
 
 /* st.c */
 extern gfc_code new_st;
index ca500f5..cedca45 100644 (file)
@@ -1915,7 +1915,7 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
                && a->expr->symtree->n.sym->attr.proc_pointer)
               || (a->expr->expr_type == EXPR_FUNCTION
                   && a->expr->symtree->n.sym->result->attr.proc_pointer)
-              || is_proc_ptr_comp (a->expr, NULL)))
+              || gfc_is_proc_ptr_comp (a->expr, NULL)))
        {
          if (where)
            gfc_error ("Expected a procedure pointer for argument '%s' at %L",
@@ -1925,7 +1925,7 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
 
       /* Satisfy 12.4.1.2 by ensuring that a procedure actual argument is
         provided for a procedure formal argument.  */
-      if (a->expr->ts.type != BT_PROCEDURE && !is_proc_ptr_comp (a->expr, NULL)
+      if (a->expr->ts.type != BT_PROCEDURE && !gfc_is_proc_ptr_comp (a->expr, NULL)
          && a->expr->expr_type == EXPR_VARIABLE
          && f->sym->attr.flavor == FL_PROCEDURE)
        {
index 1cc6e5f..9de4da2 100644 (file)
@@ -1337,7 +1337,7 @@ gfc_match_pointer_assignment (void)
     }
 
   if (lvalue->symtree->n.sym->attr.proc_pointer
-      || is_proc_ptr_comp (lvalue, NULL))
+      || gfc_is_proc_ptr_comp (lvalue, NULL))
     gfc_matching_procptr_assignment = 1;
 
   m = gfc_match (" %e%t", &rvalue);
index cc6cada..4a84aed 100644 (file)
@@ -1727,7 +1727,10 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
 
   gfc_gobble_whitespace ();
   if ((equiv_flag && gfc_peek_ascii_char () == '(')
-      || (sym->attr.dimension && !sym->attr.proc_pointer))
+      || (sym->attr.dimension && !sym->attr.proc_pointer
+         && !gfc_is_proc_ptr_comp (primary, NULL)
+         && !(gfc_matching_procptr_assignment
+              && sym->attr.flavor == FL_PROCEDURE)))
     {
       /* In EQUIVALENCE, we don't know yet whether we are seeing
         an array, character variable or array of character
index 41ac037..e3aba1a 100644 (file)
@@ -1236,7 +1236,7 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype,
          continue;
        }
 
-      if (is_proc_ptr_comp (e, &comp))
+      if (gfc_is_proc_ptr_comp (e, &comp))
        {
          e->ts = comp->ts;
          e->expr_type = EXPR_VARIABLE;
@@ -4834,7 +4834,7 @@ static gfc_try
 resolve_ppc_call (gfc_code* c)
 {
   gfc_component *comp;
-  gcc_assert (is_proc_ptr_comp (c->expr1, &comp));
+  gcc_assert (gfc_is_proc_ptr_comp (c->expr1, &comp));
 
   c->resolved_sym = c->expr1->symtree->n.sym;
   c->expr1->expr_type = EXPR_VARIABLE;
@@ -4862,7 +4862,7 @@ static gfc_try
 resolve_expr_ppc (gfc_expr* e)
 {
   gfc_component *comp;
-  gcc_assert (is_proc_ptr_comp (e, &comp));
+  gcc_assert (gfc_is_proc_ptr_comp (e, &comp));
 
   /* Convert to EXPR_FUNCTION.  */
   e->expr_type = EXPR_FUNCTION;
@@ -9034,32 +9034,40 @@ resolve_fl_derived (gfc_symbol *sym)
                resolve_intrinsic (ifc, &ifc->declared_at);
 
              if (ifc->result)
-               c->ts = ifc->result->ts;
-             else   
-               c->ts = ifc->ts;
+               {
+                 c->ts = ifc->result->ts;
+                 c->attr.allocatable = ifc->result->attr.allocatable;
+                 c->attr.pointer = ifc->result->attr.pointer;
+                 c->attr.dimension = ifc->result->attr.dimension;
+                 c->as = gfc_copy_array_spec (ifc->result->as);
+               }
+             else
+               {   
+                 c->ts = ifc->ts;
+                 c->attr.allocatable = ifc->attr.allocatable;
+                 c->attr.pointer = ifc->attr.pointer;
+                 c->attr.dimension = ifc->attr.dimension;
+                 c->as = gfc_copy_array_spec (ifc->as);
+               }
              c->ts.interface = ifc;
              c->attr.function = ifc->attr.function;
              c->attr.subroutine = ifc->attr.subroutine;
              gfc_copy_formal_args_ppc (c, ifc);
 
-             c->attr.allocatable = ifc->attr.allocatable;
-             c->attr.pointer = ifc->attr.pointer;
              c->attr.pure = ifc->attr.pure;
              c->attr.elemental = ifc->attr.elemental;
-             c->attr.dimension = ifc->attr.dimension;
              c->attr.recursive = ifc->attr.recursive;
              c->attr.always_explicit = ifc->attr.always_explicit;
-             /* Copy array spec.  */
-             c->as = gfc_copy_array_spec (ifc->as);
-             /* TODO: if (c->as)
+             /* Replace symbols in array spec.  */
+             if (c->as)
                {
                  int i;
                  for (i = 0; i < c->as->rank; i++)
                    {
-                     gfc_expr_replace_symbols (c->as->lower[i], c);
-                     gfc_expr_replace_symbols (c->as->upper[i], c);
+                     gfc_expr_replace_comp (c->as->lower[i], c);
+                     gfc_expr_replace_comp (c->as->upper[i], c);
                    }
-               }*/
+               }
              /* Copy char length.  */
              if (ifc->ts.cl)
                {
index 4b832cf..32858a7 100644 (file)
@@ -6366,7 +6366,7 @@ gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
       sym = expr->symtree->n.sym;
 
   /* A function that returns arrays.  */
-  is_proc_ptr_comp (expr, &comp);
+  gfc_is_proc_ptr_comp (expr, &comp);
   if ((!comp && gfc_return_by_reference (sym) && sym->result->attr.dimension)
       || (comp && comp->attr.dimension))
     {
index d64c3fa..0d6dc6d 100644 (file)
@@ -1015,7 +1015,7 @@ gfc_get_symbol_decl (gfc_symbol * sym)
                || sym->attr.use_assoc
                || sym->ns->proc_name->attr.if_source == IFSRC_IFBODY);
 
-  if (sym->ns && sym->ns->proc_name->attr.function)
+  if (sym->ns && sym->ns->proc_name && sym->ns->proc_name->attr.function)
     byref = gfc_return_by_reference (sym->ns->proc_name);
   else
     byref = 0;
index fe33286..b6a825a 100644 (file)
@@ -1492,7 +1492,7 @@ conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
 {
   tree tmp;
 
-  if (is_proc_ptr_comp (expr, NULL))
+  if (gfc_is_proc_ptr_comp (expr, NULL))
     tmp = gfc_get_proc_ptr_comp (se, expr);
   else if (sym->attr.dummy)
     {
@@ -2463,14 +2463,14 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 
          gfc_init_se (&fptrse, NULL);
          if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
-             || is_proc_ptr_comp (arg->next->expr, NULL))
+             || gfc_is_proc_ptr_comp (arg->next->expr, NULL))
            fptrse.want_pointer = 1;
 
          gfc_conv_expr (&fptrse, arg->next->expr);
          gfc_add_block_to_block (&se->pre, &fptrse.pre);
          gfc_add_block_to_block (&se->post, &fptrse.post);
 
-         if (is_proc_ptr_comp (arg->next->expr, NULL))
+         if (gfc_is_proc_ptr_comp (arg->next->expr, NULL))
            tmp = gfc_get_ppc_type (arg->next->expr->ref->u.c.component);
          else
            tmp = TREE_TYPE (arg->next->expr->symtree->n.sym->backend_decl);
@@ -2526,7 +2526,9 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
          return 0;
        }
     }
-  
+
+  gfc_is_proc_ptr_comp (expr, &comp);
+
   if (se->ss != NULL)
     {
       if (!sym->attr.elemental)
@@ -2534,8 +2536,9 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
          gcc_assert (se->ss->type == GFC_SS_FUNCTION);
           if (se->ss->useflags)
             {
-              gcc_assert (gfc_return_by_reference (sym)
-                      && sym->result->attr.dimension);
+             gcc_assert ((!comp && gfc_return_by_reference (sym)
+                          && sym->result->attr.dimension)
+                         || (comp && comp->attr.dimension));
               gcc_assert (se->loop != NULL);
 
               /* Access the previously obtained result.  */
@@ -2551,7 +2554,6 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 
   gfc_init_block (&post);
   gfc_init_interface_mapping (&mapping);
-  is_proc_ptr_comp (expr, &comp);
   need_interface_mapping = ((sym->ts.type == BT_CHARACTER
                                  && sym->ts.cl->length
                                  && sym->ts.cl->length->expr_type
@@ -2947,6 +2949,30 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 
          retargs = gfc_chainon_list (retargs, se->expr);
        }
+      else if (comp && comp->attr.dimension)
+       {
+         gcc_assert (se->loop && info);
+
+         /* Set the type of the array.  */
+         tmp = gfc_typenode_for_spec (&comp->ts);
+         info->dimen = se->loop->dimen;
+
+         /* Evaluate the bounds of the result, if known.  */
+         gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
+
+         /* Create a temporary to store the result.  In case the function
+            returns a pointer, the temporary will be a shallow copy and
+            mustn't be deallocated.  */
+         callee_alloc = comp->attr.allocatable || comp->attr.pointer;
+         gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
+                                      NULL_TREE, false, !comp->attr.pointer,
+                                      callee_alloc, &se->ss->expr->where);
+
+         /* Pass the temporary as the first argument.  */
+         tmp = info->descriptor;
+         tmp = gfc_build_addr_expr (NULL_TREE, tmp);
+         retargs = gfc_chainon_list (retargs, tmp);
+       }
       else if (sym->result->attr.dimension)
        {
          gcc_assert (se->loop && info);
@@ -3046,7 +3072,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
         x = f()
      where f is pointer valued, we have to dereference the result.  */
   if (!se->want_pointer && !byref && sym->attr.pointer
-      && !is_proc_ptr_comp (expr, NULL))
+      && !gfc_is_proc_ptr_comp (expr, NULL))
     se->expr = build_fold_indirect_ref (se->expr);
 
   /* f2c calling conventions require a scalar default real function to
@@ -3074,7 +3100,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 
       if (!se->direct_byref)
        {
-         if (sym->attr.dimension)
+         if (sym->attr.dimension || (comp && comp->attr.dimension))
            {
              if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
                {
@@ -3431,9 +3457,11 @@ tree
 gfc_get_proc_ptr_comp (gfc_se *se, gfc_expr *e)
 {
   gfc_se comp_se;
+  gfc_expr *e2;
   gfc_init_se (&comp_se, NULL);
-  e->expr_type = EXPR_VARIABLE;
-  gfc_conv_expr (&comp_se, e);
+  e2 = gfc_copy_expr (e);
+  e2->expr_type = EXPR_VARIABLE;
+  gfc_conv_expr (&comp_se, e2);
   comp_se.expr = build_fold_addr_expr (comp_se.expr);
   return gfc_evaluate_now (comp_se.expr, &se->pre);  
 }
@@ -4466,7 +4494,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
      functions.  */
   gcc_assert (expr2->value.function.isym
-             || (is_proc_ptr_comp (expr2, &comp)
+             || (gfc_is_proc_ptr_comp (expr2, &comp)
                  && comp && comp->attr.dimension)
              || (!comp && gfc_return_by_reference (expr2->value.function.esym)
                  && expr2->value.function.esym->result->attr.dimension));
index f8b943d..5263a67 100644 (file)
@@ -2165,7 +2165,7 @@ gfc_trans_transfer (gfc_code * code)
       /* Transfer an array. If it is an array of an intrinsic
         type, pass the descriptor to the library.  Otherwise
         scalarize the transfer.  */
-      if (expr->ref)
+      if (expr->ref && !gfc_is_proc_ptr_comp (expr, NULL))
        {
          for (ref = expr->ref; ref && ref->type != REF_ARRAY;
                 ref = ref->next);
index 736c22f..6dc3393 100644 (file)
@@ -1,3 +1,9 @@
+2009-07-09  Janus Weil  <janus@gcc.gnu.org>
+
+       PR fortran/40646
+       * gfortran.dg/proc_ptr_22.f90: New.
+       * gfortran.dg/proc_ptr_comp_12.f90: New.
+
 2009-07-09  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/40692
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_22.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_22.f90
new file mode 100644 (file)
index 0000000..6dfa1f2
--- /dev/null
@@ -0,0 +1,27 @@
+! { dg-do run }
+!
+! PR 40646: [F03] array-valued procedure pointer components
+!
+! Original test case by Charlie Sharpsteen <chuck@sharpsteen.net>
+! Modified by Janus Weil <janus@gcc.gnu.org>
+
+module bugTestMod
+  implicit none
+contains
+  function returnMat( a, b ) result( mat )
+    integer:: a, b
+    double precision, dimension(a,b):: mat 
+    mat = 1d0
+  end function returnMat
+end module bugTestMod
+
+program bugTest
+  use bugTestMod
+  implicit none
+  procedure(returnMat), pointer :: pp
+  pp => returnMat
+  if (sum(pp(2,2))/=4) call abort()
+end program bugTest
+
+! { dg-final { cleanup-modules "bugTestMod" } }
+
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_12.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_12.f90
new file mode 100644 (file)
index 0000000..314bcf8
--- /dev/null
@@ -0,0 +1,33 @@
+! { dg-do run }
+!
+! PR 40646: [F03] array-valued procedure pointer components
+!
+! Original test case by Charlie Sharpsteen <chuck@sharpsteen.net>
+! Modified by Janus Weil <janus@gcc.gnu.org>
+
+module bugTestMod
+  implicit none
+  type:: boundTest
+    procedure(returnMat), pointer, nopass:: test
+  end type boundTest
+contains
+  function returnMat( a, b ) result( mat )
+    integer:: a, b
+    double precision, dimension(a,b):: mat 
+    mat = 1d0
+  end function returnMat
+end module bugTestMod
+
+program bugTest
+  use bugTestMod
+  implicit none
+  type( boundTest ):: testObj
+  double precision, dimension(2,2):: testCatch
+  testObj%test => returnMat
+  testCatch = testObj%test(2,2)
+  print *,testCatch
+  if (sum(testCatch)/=4) call abort()
+end program bugTest
+
+! { dg-final { cleanup-modules "bugTestMod" } }
+