OSDN Git Service

2013-01-13 Paul Thomas <pault@gcc.gnu.org>
authorpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 13 Jan 2013 07:51:26 +0000 (07:51 +0000)
committerpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 13 Jan 2013 07:51:26 +0000 (07:51 +0000)
PR fortran/55618
* trans-expr.c (gfc_conv_procedure_call): Dereference scalar
character function arguments to elemental procedures in
scalarization loops.

2013-01-13  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/55618
* gfortran.dg/elemental_scalar_args_2.f90: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@195129 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/fortran/ChangeLog
gcc/fortran/resolve.c
gcc/fortran/trans-expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/elemental_scalar_args_2.f90 [new file with mode: 0644]

index 452e069..5e92fd1 100644 (file)
@@ -1,3 +1,10 @@
+2013-01-13  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/55618
+       * trans-expr.c (gfc_conv_procedure_call): Dereference scalar
+       character function arguments to elemental procedures in
+       scalarization loops.
+
 2013-01-08  Mikael Morin  <mikael@gcc.gnu.org>
 
        PR fortran/42769
 
        PR fortran/50981
        * trans-array.c (gfc_walk_elemental_function_args): Fix
-       passing of deallocated allocatables/pointers as absent argument. 
+       passing of deallocated allocatables/pointers as absent argument.
 
 2012-01-16  Tobias Burnus  <burnus@net-b.de>
 
 2012-01-16  Paul Thomas  <pault@gcc.gnu.org>
 
        * trans-array.c (gfc_trans_create_temp_array): In the case of a
-       class array temporary, detect a null 'eltype' on entry and use 
+       class array temporary, detect a null 'eltype' on entry and use
        'initial' to provde the class reference and so, through the
        vtable, the element size for the dynamic type.
        * trans-stmt.c (gfc_conv_elemental_dependencies): For class
index 18e94a1..471fa61 100644 (file)
@@ -94,7 +94,7 @@ static bool
 is_sym_host_assoc (gfc_symbol *sym, gfc_namespace *ns)
 {
   for (ns = ns->parent; ns; ns = ns->parent)
-    {      
+    {
       if (sym->ns == ns)
        return true;
     }
@@ -165,7 +165,7 @@ resolve_procedure_interface (gfc_symbol *sym)
          sym->ts = ifc->result->ts;
          sym->result = sym;
        }
-      else   
+      else
        sym->ts = ifc->ts;
       sym->ts.interface = ifc;
       sym->attr.function = ifc->attr.function;
@@ -513,7 +513,7 @@ resolve_contained_fntype (gfc_symbol *sym, gfc_namespace *ns)
        }
     }
 
-  /* Fortran 95 Draft Standard, page 51, Section 5.1.1.5, on the Character 
+  /* Fortran 95 Draft Standard, page 51, Section 5.1.1.5, on the Character
      type, lists the only ways a character length value of * can be used:
      dummy arguments of procedures, named constants, and function results
      in external functions.  Internal function results and results of module
@@ -1255,7 +1255,7 @@ generic_sym (gfc_symbol *sym)
     return 0;
 
   gfc_find_symbol (sym->name, sym->ns->parent, 1, &s);
-  
+
   if (s != NULL)
     {
       if (s == sym)
@@ -1376,7 +1376,7 @@ count_specific_procs (gfc_expr *e)
   int n;
   gfc_interface *p;
   gfc_symbol *sym;
-       
+
   n = 0;
   sym = e->symtree->n.sym;
 
@@ -1579,7 +1579,7 @@ resolve_procedure_expression (gfc_expr* expr)
     gfc_warning ("Non-RECURSIVE procedure '%s' at %L is possibly calling"
                 " itself recursively.  Declare it RECURSIVE or use"
                 " -frecursive", sym->name, &expr->where);
-  
+
   return SUCCESS;
 }
 
@@ -1687,7 +1687,7 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype,
            with the same name before emitting an error.  */
          if (sym->attr.generic && count_specific_procs (e) != 1)
            return FAILURE;
-         
+
          /* Just in case a specific was found for the expression.  */
          sym = e->symtree->n.sym;
 
@@ -1876,7 +1876,7 @@ resolve_elemental_actual (gfc_expr *expr, gfc_code *c)
   else if (c && c->ext.actual != NULL)
     {
       arg0 = c->ext.actual;
-      
+
       if (c->resolved_sym)
        esym = c->resolved_sym;
       else
@@ -2275,7 +2275,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *where,
              && !(gfc_option.warn_std & GFC_STD_GNU)))
        gfc_errors_to_warnings (1);
 
-      if (sym->attr.if_source != IFSRC_IFBODY)  
+      if (sym->attr.if_source != IFSRC_IFBODY)
        gfc_procedure_use (def_sym, actual, where);
 
       gfc_errors_to_warnings (0);
@@ -2679,7 +2679,7 @@ is_scalar_expr_ptr (gfc_expr *expr)
                    {
                      /* We have constant lower and upper bounds.  If the
                         difference between is 1, it can be considered a
-                        scalar.  
+                        scalar.
                         FIXME: Use gfc_dep_compare_expr instead.  */
                      start = (int) mpz_get_si
                                (ref->u.ar.as->lower[0]->value.integer);
@@ -2746,7 +2746,7 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_actual_arglist *args,
      the actual expression could be a part-ref of the expr symbol.  */
   arg_ts = &(args->expr->ts);
   arg_attr = gfc_expr_attr (args->expr);
-    
+
   if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
     {
       /* If the user gave two args then they are providing something for
@@ -2835,7 +2835,7 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_actual_arglist *args,
          if (seen_section && retval == SUCCESS)
            gfc_warning ("Array section in '%s' call at %L", name,
                         &(args->expr->where));
-                        
+
           /* See if we have interoperable type and type param.  */
           if (gfc_verify_c_interop (arg_ts) == SUCCESS
               || gfc_check_any_c_kind (arg_ts) == SUCCESS)
@@ -2849,7 +2849,7 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_actual_arglist *args,
                      is not an array of zero size.  */
                   if (args_sym->attr.allocatable == 1)
                     {
-                      if (args_sym->attr.dimension != 0 
+                      if (args_sym->attr.dimension != 0
                           && (args_sym->as && args_sym->as->rank == 0))
                         {
                           gfc_error_now ("Allocatable variable '%s' used as a "
@@ -2888,7 +2888,7 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_actual_arglist *args,
                              retval = FAILURE;
                            }
                        }
-                              
+
                       /* Make sure it's not a character string.  Arrays of
                          any type should be ok if the variable is of a C
                          interoperable type.  */
@@ -2928,7 +2928,7 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_actual_arglist *args,
                  with no length type parameters.  It still must have either
                  the pointer or target attribute, and it can be
                  allocatable (but must be allocated when c_loc is called).  */
-              if (args->expr->rank != 0 
+              if (args->expr->rank != 0
                   && is_scalar_expr_ptr (args->expr) != SUCCESS)
                 {
                   gfc_error_now ("Parameter '%s' to '%s' at %L must be a "
@@ -2936,7 +2936,7 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_actual_arglist *args,
                                  &(args->expr->where));
                   retval = FAILURE;
                 }
-              else if (arg_ts->type == BT_CHARACTER 
+              else if (arg_ts->type == BT_CHARACTER
                        && is_scalar_expr_ptr (args->expr) != SUCCESS)
                 {
                   gfc_error_now ("CHARACTER argument '%s' to '%s' at "
@@ -2975,7 +2975,7 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_actual_arglist *args,
              retval = FAILURE;
            }
         }
-      
+
       /* for c_loc/c_funloc, the new symbol is the same as the old one */
       *new_sym = sym;
     }
@@ -3010,7 +3010,7 @@ resolve_function (gfc_expr *expr)
   /* If this is a procedure pointer component, it has already been resolved.  */
   if (gfc_is_proc_ptr_comp (expr, NULL))
     return SUCCESS;
-  
+
   if (sym && sym->attr.intrinsic
       && resolve_intrinsic (sym, &expr->where) == FAILURE)
     return FAILURE;
@@ -3049,7 +3049,7 @@ resolve_function (gfc_expr *expr)
     }
 
   inquiry_argument = false;
+
   /* Need to setup the call to the correct c_associated, depending on
      the number of cptrs to user gives to compare.  */
   if (sym && sym->attr.is_iso_c == 1)
@@ -3057,12 +3057,12 @@ resolve_function (gfc_expr *expr)
       if (gfc_iso_c_func_interface (sym, expr->value.function.actual, &sym)
           == FAILURE)
         return FAILURE;
-      
+
       /* Get the symtree for the new symbol (resolved func).
          the old one will be freed later, when it's no longer used.  */
       gfc_find_sym_tree (sym->name, sym->ns, 1, &(expr->symtree));
     }
-  
+
   /* Resume assumed_size checking.  */
   need_full_assumed_size--;
 
@@ -3391,7 +3391,7 @@ set_name_and_label (gfc_code *c, gfc_symbol *sym,
       sprintf (name, "%s_%c%d", sym->name, type, kind);
       /* Set up the binding label as the given symbol's label plus
          the type and kind.  */
-      *binding_label = gfc_get_string ("%s_%c%d", sym->binding_label, type, 
+      *binding_label = gfc_get_string ("%s_%c%d", sym->binding_label, type,
                                       kind);
     }
   else
@@ -3402,7 +3402,7 @@ set_name_and_label (gfc_code *c, gfc_symbol *sym,
       sprintf (name, "%s", sym->name);
       *binding_label = sym->binding_label;
     }
-   
+
   return;
 }
 
@@ -3426,7 +3426,7 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym)
   /* default to success; will override if find error */
   match m = MATCH_YES;
 
-  /* Make sure the actual arguments are in the necessary order (based on the 
+  /* Make sure the actual arguments are in the necessary order (based on the
      formal args) before resolving.  */
   gfc_procedure_use (sym, &c->ext.actual, &(c->loc));
 
@@ -3434,7 +3434,7 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym)
       (sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER))
     {
       set_name_and_label (c, sym, name, &binding_label);
-      
+
       if (sym->intmod_sym_id == ISOCBINDING_F_POINTER)
        {
          if (c->ext.actual != NULL && c->ext.actual->next != NULL)
@@ -3445,7 +3445,7 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym)
                 gfc_procedure_use() (called above to sort actual args).  */
              if (c->ext.actual->next->expr->rank != 0)
                {
-                 if(c->ext.actual->next->next == NULL 
+                 if(c->ext.actual->next->next == NULL
                     || c->ext.actual->next->next->expr == NULL)
                    {
                      m = MATCH_ERROR;
@@ -3464,12 +3464,12 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym)
                }
            }
        }
-      
+
       if (m != MATCH_ERROR)
        {
          /* the 1 means to add the optional arg to formal list */
          new_sym = get_iso_c_sym (sym, name, binding_label, 1);
-        
+
          /* for error reporting, say it's declared where the original was */
          new_sym->declared_at = sym->declared_at;
        }
@@ -3485,7 +3485,7 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym)
     c->resolved_sym = new_sym;
   else
     c->resolved_sym = sym;
-  
+
   return m;
 }
 
@@ -3502,7 +3502,7 @@ resolve_specific_s0 (gfc_code *c, gfc_symbol *sym)
       m = gfc_iso_c_sub_interface (c,sym);
       return m;
     }
-  
+
   if (sym->attr.external || sym->attr.if_source == IFSRC_IFBODY)
     {
       if (sym->attr.dummy)
@@ -3921,7 +3921,7 @@ resolve_operator (gfc_expr *e)
       if (op1->ts.type == BT_LOGICAL && op2->ts.type == BT_LOGICAL)
        sprintf (msg,
                 _("Logicals at %%L must be compared with %s instead of %s"),
-                (e->value.op.op == INTRINSIC_EQ 
+                (e->value.op.op == INTRINSIC_EQ
                  || e->value.op.op == INTRINSIC_EQ_OS)
                 ? ".eqv." : ".neqv.", gfc_op2string (e->value.op.op));
       else
@@ -4161,7 +4161,7 @@ compare_bound_mpz_t (gfc_expr *a, mpz_t b)
 }
 
 
-/* Compute the last value of a sequence given by a triplet.  
+/* Compute the last value of a sequence given by a triplet.
    Return 0 if it wasn't able to compute the last value, or if the
    sequence if empty, and 1 otherwise.  */
 
@@ -6003,7 +6003,7 @@ resolve_typebound_function (gfc_expr* e)
       e->value.function.esym = NULL;
       e->symtree = st;
 
-      if (new_ref)  
+      if (new_ref)
        e->ref = new_ref;
 
       /* '_vptr' points to the vtab, which contains the procedure pointers.  */
@@ -6321,7 +6321,7 @@ gfc_resolve_expr (gfc_expr *e)
       if (t == SUCCESS && e->ts.type == BT_CHARACTER)
         {
          /* For efficiency, we call gfc_expand_constructor for BT_CHARACTER
-            here rather then add a duplicate test for it above.  */ 
+            here rather then add a duplicate test for it above.  */
          gfc_expand_constructor (e, false);
          t = gfc_resolve_character_array_constructor (e);
        }
@@ -6478,7 +6478,7 @@ forall_index (gfc_expr *expr, gfc_symbol *sym, int *f)
 {
   if (expr->expr_type != EXPR_VARIABLE)
     return false;
-  
+
   /* A scalar assignment  */
   if (!expr->ref || *f == 1)
     {
@@ -6761,7 +6761,7 @@ remove_last_array_ref (gfc_expr* e)
 
 
 /* Used in resolve_allocate_expr to check that a allocation-object and
-   a source-expr are conformable.  This does not catch all possible 
+   a source-expr are conformable.  This does not catch all possible
    cases; in particular a runtime checking is needed.  */
 
 static gfc_try
@@ -6769,7 +6769,7 @@ conformable_arrays (gfc_expr *e1, gfc_expr *e2)
 {
   gfc_ref *tail;
   for (tail = e2->ref; tail && tail->next; tail = tail->next);
-  
+
   /* First compare rank.  */
   if (tail && e1->rank != tail->u.ar.as->rank)
     {
@@ -7032,7 +7032,7 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code)
         using _copy and trans_call. It is convenient to exploit that
         when the allocated type is different from the declared type but
         no SOURCE exists by setting expr3.  */
-      code->expr3 = gfc_default_initializer (&code->ext.alloc.ts); 
+      code->expr3 = gfc_default_initializer (&code->ext.alloc.ts);
     }
   else if (!code->expr3)
     {
@@ -7293,7 +7293,7 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn)
              /* This is a potential collision.  */
              gfc_ref *pr = pe->ref;
              gfc_ref *qr = qe->ref;
-             
+
              /* Follow the references  until
                 a) They start to differ, in which case there is no error;
                 you can deallocate a%b and a%c in a single statement
@@ -7348,7 +7348,7 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn)
                      if (pr->u.c.component->name != qr->u.c.component->name)
                        break;
                    }
-                 
+
                  pr = pr->next;
                  qr = qr->next;
                }
@@ -7375,7 +7375,7 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn)
 
 /* Callback function for our mergesort variant.  Determines interval
    overlaps for CASEs. Return <0 if op1 < op2, 0 for overlap, >0 for
-   op1 > op2.  Assumes we're not dealing with the default case.  
+   op1 > op2.  Assumes we're not dealing with the default case.
    We have op1 = (:L), (K:L) or (K:) and op2 = (:N), (M:N) or (M:).
    There are nine situations to check.  */
 
@@ -8066,7 +8066,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
          default_case = body;
        }
     }
-    
+
   if (error > 0)
     return;
 
@@ -8085,7 +8085,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
       assoc->target = gfc_copy_expr (code->expr2);
       assoc->target->where = code->expr2->where;
       /* assoc->variable will be set by resolve_assoc_var.  */
-      
+
       code->ext.block.assoc = assoc;
       code->expr1->symtree->n.sym->assoc = assoc;
 
@@ -8156,7 +8156,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
 
       resolve_assoc_var (st->n.sym, false);
     }
-    
+
   /* Take out CLASS IS cases for separate treatment.  */
   body = code;
   while (body && body->block)
@@ -8165,7 +8165,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
        {
          /* Add to class_is list.  */
          if (class_is == NULL)
-           { 
+           {
              class_is = body->block;
              tail = class_is;
            }
@@ -8186,7 +8186,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
   if (class_is)
     {
       gfc_symbol *vtab;
-      
+
       if (!default_case)
        {
          /* Add a default case to hold the CLASS IS cases.  */
@@ -8234,7 +8234,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
            }
          while (swapped);
        }
-       
+
       /* Generate IF chain.  */
       if_st = gfc_get_code ();
       if_st->op = EXEC_IF;
@@ -8270,7 +8270,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
            new_st->op = EXEC_IF;
            new_st->next = default_case->next;
          }
-         
+
        /* Replace CLASS DEFAULT code by the IF chain.  */
        default_case->next = if_st;
     }
@@ -8287,7 +8287,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
 
 /* Resolve a transfer statement. This is making sure that:
    -- a derived type being transferred has only non-pointer components
-   -- a derived type being transferred doesn't have private components, unless 
+   -- a derived type being transferred doesn't have private components, unless
       it's being transferred from the module where the type was defined
    -- we're not trying to transfer a whole assumed size array.  */
 
@@ -8391,7 +8391,7 @@ resolve_transfer (gfc_code *code)
 
 /* Find the set of labels that are reachable from this block.  We also
    record the last statement in each block.  */
-     
+
 static void
 find_reachable_labels (gfc_code *block)
 {
@@ -8697,7 +8697,7 @@ resolve_where (gfc_code *code, gfc_expr *mask)
                          "inconsistent shape", &cnext->expr1->where);
              break;
 
-  
+
            case EXEC_ASSIGN_CALL:
              resolve_call (cnext);
              if (!cnext->resolved_sym->attr.elemental)
@@ -8783,7 +8783,7 @@ gfc_resolve_where_code_in_forall (gfc_code *code, int nvar,
            case EXEC_ASSIGN:
              gfc_resolve_assign_in_forall (cnext, nvar, var_expr);
              break;
-  
+
            /* WHERE operator assignment statement */
            case EXEC_ASSIGN_CALL:
              resolve_call (cnext);
@@ -8851,10 +8851,10 @@ gfc_resolve_forall_body (gfc_code *code, int nvar, gfc_expr **var_expr)
 
 
 /* Counts the number of iterators needed inside a forall construct, including
-   nested forall constructs. This is used to allocate the needed memory 
+   nested forall constructs. This is used to allocate the needed memory
    in gfc_resolve_forall.  */
 
-static int 
+static int
 gfc_count_forall_iterators (gfc_code *code)
 {
   int max_iters, sub_iters, current_iters;
@@ -8866,11 +8866,11 @@ gfc_count_forall_iterators (gfc_code *code)
 
   for (fa = code->ext.forall_iterator; fa; fa = fa->next)
     current_iters ++;
-  
+
   code = code->block->next;
 
   while (code)
-    {          
+    {
       if (code->op == EXEC_FORALL)
         {
           sub_iters = gfc_count_forall_iterators (code);
@@ -9653,7 +9653,7 @@ resolve_values (gfc_symbol *sym)
 
   if (sym->value->expr_type == EXPR_STRUCTURE)
     t= resolve_structure_cons (sym->value, 1);
-  else 
+  else
     t = gfc_resolve_expr (sym->value);
 
   if (t == FAILURE)
@@ -9675,7 +9675,7 @@ resolve_bind_c_comms (gfc_symtree *comm_block_tree)
     {
       gfc_gsymbol *binding_label_gsym;
       gfc_gsymbol *comm_name_gsym;
-      const char * bind_label = comm_block_tree->n.common->binding_label 
+      const char * bind_label = comm_block_tree->n.common->binding_label
        ? comm_block_tree->n.common->binding_label : "";
 
       /* See if a global symbol exists by the common block's name.  It may
@@ -9718,7 +9718,7 @@ resolve_bind_c_comms (gfc_symtree *comm_block_tree)
          check and nothing to add as a global symbol for the label.  */
       if (!comm_block_tree->n.common->binding_label)
         return;
-      
+
       binding_label_gsym =
         gfc_find_gsymbol (gfc_gsym_root,
                           comm_block_tree->n.common->binding_label);
@@ -9755,7 +9755,7 @@ resolve_bind_c_comms (gfc_symtree *comm_block_tree)
                        comm_name_gsym->name, &(comm_name_gsym->where));
         }
     }
-  
+
   return;
 }
 
@@ -9769,34 +9769,34 @@ resolve_bind_c_derived_types (gfc_symbol *derived_sym)
   if (derived_sym != NULL && derived_sym->attr.flavor == FL_DERIVED
       && derived_sym->attr.is_bind_c == 1)
     verify_bind_c_derived_type (derived_sym);
-  
+
   return;
 }
 
 
-/* Verify that any binding labels used in a given namespace do not collide 
+/* Verify that any binding labels used in a given namespace do not collide
    with the names or binding labels of any global symbols.  */
 
 static void
 gfc_verify_binding_labels (gfc_symbol *sym)
 {
   int has_error = 0;
-  
-  if (sym != NULL && sym->attr.is_bind_c && sym->attr.is_iso_c == 0 
+
+  if (sym != NULL && sym->attr.is_bind_c && sym->attr.is_iso_c == 0
       && sym->attr.flavor != FL_DERIVED && sym->binding_label)
     {
       gfc_gsymbol *bind_c_sym;
 
       bind_c_sym = gfc_find_gsymbol (gfc_gsym_root, sym->binding_label);
-      if (bind_c_sym != NULL 
+      if (bind_c_sym != NULL
           && strcmp (bind_c_sym->name, sym->binding_label) == 0)
         {
-          if (sym->attr.if_source == IFSRC_DECL 
-              && (bind_c_sym->type != GSYM_SUBROUTINE 
-                  && bind_c_sym->type != GSYM_FUNCTION) 
-              && ((sym->attr.contained == 1 
-                   && strcmp (bind_c_sym->sym_name, sym->name) != 0) 
-                  || (sym->attr.use_assoc == 1 
+          if (sym->attr.if_source == IFSRC_DECL
+              && (bind_c_sym->type != GSYM_SUBROUTINE
+                  && bind_c_sym->type != GSYM_FUNCTION)
+              && ((sym->attr.contained == 1
+                   && strcmp (bind_c_sym->sym_name, sym->name) != 0)
+                  || (sym->attr.use_assoc == 1
                       && (strcmp (bind_c_sym->mod_name, sym->module) != 0))))
             {
               /* Make sure global procedures don't collide with anything.  */
@@ -9806,10 +9806,10 @@ gfc_verify_binding_labels (gfc_symbol *sym)
                          &(bind_c_sym->where));
               has_error = 1;
             }
-          else if (sym->attr.contained == 0 
-                   && (sym->attr.if_source == IFSRC_IFBODY 
-                       && sym->attr.flavor == FL_PROCEDURE) 
-                   && (bind_c_sym->sym_name != NULL 
+          else if (sym->attr.contained == 0
+                   && (sym->attr.if_source == IFSRC_IFBODY
+                       && sym->attr.flavor == FL_PROCEDURE)
+                   && (bind_c_sym->sym_name != NULL
                        && strcmp (bind_c_sym->sym_name, sym->name) != 0))
             {
               /* Make sure procedures in interface bodies don't collide.  */
@@ -9820,10 +9820,10 @@ gfc_verify_binding_labels (gfc_symbol *sym)
                          &(bind_c_sym->where));
               has_error = 1;
             }
-          else if (sym->attr.contained == 0 
+          else if (sym->attr.contained == 0
                    && sym->attr.if_source == IFSRC_UNKNOWN)
            if ((sym->attr.use_assoc && bind_c_sym->mod_name
-                && strcmp (bind_c_sym->mod_name, sym->module) != 0) 
+                && strcmp (bind_c_sym->mod_name, sym->module) != 0)
                || sym->attr.use_assoc == 0)
               {
                 gfc_error ("Binding label '%s' at %L collides with global "
@@ -10019,7 +10019,7 @@ apply_default_init (gfc_symbol *sym)
 
 /* Build an initializer for a local integer, real, complex, logical, or
    character variable, based on the command line flags finit-local-zero,
-   finit-integer=, finit-real=, finit-logical=, and finit-runtime.  Returns 
+   finit-integer=, finit-real=, finit-logical=, and finit-runtime.  Returns
    null if the symbol should not have a default initialization.  */
 static gfc_expr *
 build_default_init_expr (gfc_symbol *sym)
@@ -10050,10 +10050,10 @@ build_default_init_expr (gfc_symbol *sym)
      characters, and only if the corresponding command-line flags
      were set.  Otherwise, we free init_expr and return null.  */
   switch (sym->ts.type)
-    {    
+    {
     case BT_INTEGER:
       if (gfc_option.flag_init_integer != GFC_INIT_INTEGER_OFF)
-       mpz_set_si (init_expr->value.integer, 
+       mpz_set_si (init_expr->value.integer,
                         gfc_option.flag_init_integer_value);
       else
        {
@@ -10090,7 +10090,7 @@ build_default_init_expr (gfc_symbol *sym)
          break;
        }
       break;
-         
+
     case BT_COMPLEX:
       switch (gfc_option.flag_init_real)
        {
@@ -10122,7 +10122,7 @@ build_default_init_expr (gfc_symbol *sym)
          break;
        }
       break;
-         
+
     case BT_LOGICAL:
       if (gfc_option.flag_init_logical == GFC_INIT_LOGICAL_FALSE)
        init_expr->value.logical = 0;
@@ -10134,9 +10134,9 @@ build_default_init_expr (gfc_symbol *sym)
          init_expr = NULL;
        }
       break;
-         
+
     case BT_CHARACTER:
-      /* For characters, the length must be constant in order to 
+      /* For characters, the length must be constant in order to
         create a default initializer.  */
       if (gfc_option.flag_init_character == GFC_INIT_CHARACTER_ON
          && sym->ts.u.cl->length
@@ -10175,7 +10175,7 @@ build_default_init_expr (gfc_symbol *sym)
          init_expr->value.function.actual = arg;
        }
       break;
-         
+
     default:
      gfc_free_expr (init_expr);
      init_expr = NULL;
@@ -10203,7 +10203,7 @@ apply_default_init_local (gfc_symbol *sym)
   /* For saved variables, we don't want to add an initializer at function
      entry, so we just add a static initializer. Note that automatic variables
      are stack allocated even with -fno-automatic.  */
-  if (sym->attr.save || sym->ns->save_all 
+  if (sym->attr.save || sym->ns->save_all
       || (gfc_option.flag_max_stack_var_size == 0
          && (!sym->attr.dimension || !is_non_constant_shape_array (sym))))
     {
@@ -10308,7 +10308,7 @@ resolve_fl_var_and_proc (gfc_symbol *sym, int mp_flag)
          return FAILURE;
        }
     }
-    
+
   return SUCCESS;
 }
 
@@ -10730,7 +10730,7 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
           sym->attr.is_c_interop = 1;
           sym->ts.is_c_interop = 1;
         }
-      
+
       curr_arg = sym->formal;
       while (curr_arg != NULL)
         {
@@ -10742,7 +10742,7 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
                 BIND(C) to try and prevent multiple errors being
                 reported.  */
              has_non_interop_arg = 1;
-          
+
           curr_arg = curr_arg->next;
         }
 
@@ -10755,7 +10755,7 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
          sym->attr.is_bind_c = 0;
        }
     }
-  
+
   if (!sym->attr.proc_pointer)
     {
       if (sym->attr.save == SAVE_EXPLICIT)
@@ -10906,7 +10906,7 @@ gfc_resolve_finalizers (gfc_symbol* derived)
                {
                  gfc_error ("FINAL procedure '%s' declared at %L has the same"
                             " rank (%d) as '%s'",
-                            list->proc_sym->name, &list->where, my_rank, 
+                            list->proc_sym->name, &list->where, my_rank,
                             i->proc_sym->name);
                  goto error;
                }
@@ -11156,7 +11156,7 @@ resolve_typebound_intrinsic_op (gfc_symbol* derived, gfc_intrinsic_op op,
 {
   gfc_symbol* super_type;
   gfc_tbp_generic* target;
-  
+
   /* If there's already an error here, do nothing (but don't fail again).  */
   if (p->error)
     return SUCCESS;
@@ -11381,7 +11381,7 @@ resolve_typebound_procedure (gfc_symtree* stree)
                     me_arg->name, &where, resolve_bindings_derived->name);
          goto error;
        }
-  
+
       gcc_assert (me_arg->ts.type == BT_CLASS);
       if (CLASS_DATA (me_arg)->as && CLASS_DATA (me_arg)->as->rank > 0)
        {
@@ -11458,7 +11458,7 @@ resolve_typebound_procedures (gfc_symbol* derived)
 
   if (!derived->f2k_derived || !derived->f2k_derived->tb_sym_root)
     return SUCCESS;
-  
+
   super_type = gfc_get_derived_super_type (derived);
   if (super_type)
     resolve_typebound_procedures (super_type);
@@ -11551,7 +11551,7 @@ ensure_not_abstract (gfc_symbol* sub, gfc_symbol* ancestor)
      clearer than something sophisticated.  */
 
   gcc_assert (ancestor && !sub->attr.abstract);
-  
+
   if (!ancestor->attr.abstract)
     return SUCCESS;
 
@@ -11685,7 +11685,7 @@ resolve_fl_derived0 (gfc_symbol *sym)
                  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;
@@ -11854,7 +11854,7 @@ resolve_fl_derived0 (gfc_symbol *sym)
              || (!sym->attr.is_class && c == sym->components))
          && strcmp (super_type->name, c->name) == 0)
        c->attr.access = super_type->attr.access;
-      
+
       /* If this type is an extension, see if this component has the same name
         as an inherited type-bound procedure.  */
       if (super_type && !sym->attr.is_class
@@ -12028,10 +12028,10 @@ resolve_fl_derived (gfc_symbol *sym)
          vptr->ts.u.derived = vtab->ts.u.derived;
        }
     }
-  
+
   if (resolve_fl_derived0 (sym) == FAILURE)
     return FAILURE;
-  
+
   /* Resolve the type-bound procedures.  */
   if (resolve_typebound_procedures (sym) == FAILURE)
     return FAILURE;
@@ -12039,7 +12039,7 @@ resolve_fl_derived (gfc_symbol *sym)
   /* Resolve the finalizer procedures.  */
   if (gfc_resolve_finalizers (sym) == FAILURE)
     return FAILURE;
-  
+
   return SUCCESS;
 }
 
@@ -12186,7 +12186,7 @@ static gfc_try
 resolve_fl_parameter (gfc_symbol *sym)
 {
   /* A parameter array's shape needs to be constant.  */
-  if (sym->as != NULL 
+  if (sym->as != NULL
       && (sym->as->type == AS_DEFERRED
           || is_non_constant_shape_array (sym)))
     {
@@ -12301,8 +12301,8 @@ resolve_symbol (gfc_symbol *sym)
      can.  */
   mp_flag = (sym->result != NULL && sym->result != sym);
 
-  /* Make sure that the intrinsic is consistent with its internal 
-     representation. This needs to be done before assigning a default 
+  /* Make sure that the intrinsic is consistent with its internal
+     representation. This needs to be done before assigning a default
      type to avoid spurious warnings.  */
   if (sym->attr.flavor != FL_MODULE && sym->attr.intrinsic
       && resolve_intrinsic (sym, &sym->declared_at) == FAILURE)
@@ -12461,7 +12461,7 @@ resolve_symbol (gfc_symbol *sym)
       sym->attr.flavor != FL_PROCEDURE && sym->attr.flavor != FL_DERIVED)
     {
       gfc_try t = SUCCESS;
-      
+
       /* First, make sure the variable is declared at the
         module-level scope (J3/04-007, Section 15.3).  */
       if (sym->ns->proc_name->attr.flavor != FL_MODULE &&
@@ -12491,7 +12491,7 @@ resolve_symbol (gfc_symbol *sym)
                 verify_bind_c_derived_type (sym->ts.u.derived);
               t = FAILURE;
             }
-         
+
          /* Verify the variable itself as C interoperable if it
              is BIND(C).  It is not possible for this to succeed if
              the verify_bind_c_derived_type failed, so don't have to handle
@@ -13263,12 +13263,12 @@ gfc_implicit_pure (gfc_symbol *sym)
          sym = ns->proc_name;
          if (sym == NULL)
            return 0;
-         
+
          if (sym->attr.flavor == FL_PROCEDURE)
            break;
        }
     }
-  
+
   return sym->attr.flavor == FL_PROCEDURE && sym->attr.implicit_pure
     && !sym->attr.pure;
 }
@@ -13439,7 +13439,7 @@ resolve_equivalence_derived (gfc_symbol *derived, gfc_symbol *sym, gfc_expr *e)
 }
 
 
-/* Resolve equivalence object. 
+/* Resolve equivalence object.
    An EQUIVALENCE object shall not be a dummy argument, a pointer, a target,
    an allocatable array, an object of nonsequence derived type, an object of
    sequence derived type containing a pointer at any level of component
index 94bd041..b54a28e 100644 (file)
@@ -1,6 +1,6 @@
 /* Expression translation
    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011, 2012
+   2011, 2012, 2013
    Free Software Foundation, Inc.
    Contributed by Paul Brook <paul@nowt.org>
    and Steven Bosscher <s.bosscher@student.tudelft.nl>
@@ -148,7 +148,7 @@ gfc_vtable_copy_get (tree decl)
 
 
 /* Takes a derived type expression and returns the address of a temporary
-   class object of the 'declared' type.  */ 
+   class object of the 'declared' type.  */
 static void
 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
                           gfc_typespec class_ts)
@@ -211,10 +211,10 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
 
 /* Takes a scalarized class array expression and returns the
    address of a temporary scalar class object of the 'declared'
-   type.  
+   type.
    OOP-TODO: This could be improved by adding code that branched on
    the dynamic type being the same as the declared type. In this case
-   the original class expression can be passed directly.  */ 
+   the original class expression can be passed directly.  */
 void
 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e,
                         gfc_typespec class_ts, bool elemental)
@@ -267,7 +267,7 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e,
 
   tmp = NULL_TREE;
   if (class_ref == NULL
-       && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS) 
+       && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
     tmp = e->symtree->n.sym->backend_decl;
   else
     {
@@ -481,7 +481,7 @@ gfc_trans_class_init_assign (gfc_code *code)
       tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
     }
   gfc_add_expr_to_block (&block, tmp);
-  
+
   return gfc_finish_block (&block);
 }
 
@@ -727,7 +727,7 @@ gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
       tmp = gfc_get_int_type (kind);
       tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
                                                        se->expr));
-    
+
       /* Test for a NULL value.  */
       tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
                        tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
@@ -764,9 +764,9 @@ gfc_get_expr_charlen (gfc_expr *e)
   gfc_ref *r;
   tree length;
 
-  gcc_assert (e->expr_type == EXPR_VARIABLE 
+  gcc_assert (e->expr_type == EXPR_VARIABLE
              && e->ts.type == BT_CHARACTER);
-  
+
   length = NULL; /* To silence compiler warning.  */
 
   if (is_subref_array (e) && e->ts.u.cl->length)
@@ -855,8 +855,8 @@ flatten_array_ctors_without_strlen (gfc_expr* e)
     {
 
     case EXPR_OP:
-      flatten_array_ctors_without_strlen (e->value.op.op1); 
-      flatten_array_ctors_without_strlen (e->value.op.op2); 
+      flatten_array_ctors_without_strlen (e->value.op.op1);
+      flatten_array_ctors_without_strlen (e->value.op.op2);
       break;
 
     case EXPR_COMPCALL:
@@ -1221,7 +1221,7 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
        se_expr = gfc_get_fake_result_decl (sym, parent_flag);
 
       /* Similarly for alternate entry points.  */
-      else if (alternate_entry 
+      else if (alternate_entry
               && (sym->ns->proc_name->backend_decl == current_function_decl
                   || parent_flag))
        {
@@ -1257,7 +1257,7 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
 
 
       /* Dereference the expression, where needed. Since characters
-        are entirely different from other types, they are treated 
+        are entirely different from other types, they are treated
         separately.  */
       if (sym->ts.type == BT_CHARACTER)
        {
@@ -1287,7 +1287,7 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
            se->expr = build_fold_indirect_ref_loc (input_location,
                                                se->expr);
 
-         /* Dereference non-character pointer variables. 
+         /* Dereference non-character pointer variables.
             These must be dummies, results, or scalars.  */
          if ((sym->attr.pointer || sym->attr.allocatable
               || gfc_is_associate_pointer (sym))
@@ -1359,7 +1359,7 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
     {
       if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr, NULL))
        gfc_conv_string_parameter (se);
-      else 
+      else
        se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
     }
 }
@@ -1441,11 +1441,11 @@ static const unsigned char powi_table[POWI_TABLE_SIZE] =
     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
   };
 
-/* If n is larger than lookup table's max index, we use the "window 
+/* If n is larger than lookup table's max index, we use the "window
    method".  */
 #define POWI_WINDOW_SIZE 3
 
-/* Recursive function to expand the power operator. The temporary 
+/* Recursive function to expand the power operator. The temporary
    values are put in tmpvar. The function returns tmpvar[1] ** n.  */
 static tree
 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
@@ -1508,7 +1508,7 @@ gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
   /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
      of the asymmetric range of the integer type.  */
   n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
-  
+
   type = TREE_TYPE (lhs);
   sgn = tree_int_cst_sgn (rhs);
 
@@ -1619,7 +1619,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
        case 4:
          ikind = 0;
          break;
-         
+
        case 8:
          ikind = 1;
          break;
@@ -1647,7 +1647,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
        case 4:
          kind = 0;
          break;
-         
+
        case 8:
          kind = 1;
          break;
@@ -1663,7 +1663,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
        default:
          gcc_unreachable ();
        }
-      
+
       switch (expr->value.op.op1->ts.type)
        {
        case BT_INTEGER:
@@ -1681,7 +1681,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
                case 0:
                  fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
                  break;
-               
+
                case 1:
                  fndecl = builtin_decl_explicit (BUILT_IN_POWI);
                  break;
@@ -1691,7 +1691,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
                  break;
 
                case 3:
-                 /* Use the __builtin_powil() only if real(kind=16) is 
+                 /* Use the __builtin_powil() only if real(kind=16) is
                     actually the C long double type.  */
                  if (!gfc_real16_is_float128)
                    fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
@@ -1702,7 +1702,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
                }
            }
 
-         /* If we don't have a good builtin for this, go for the 
+         /* If we don't have a good builtin for this, go for the
             library function.  */
          if (!fndecl)
            fndecl = gfor_fndecl_math_powi[kind][ikind].real;
@@ -2109,7 +2109,7 @@ gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
                                    (int)(*expr)->value.character.string[0]);
          if ((*expr)->ts.kind != gfc_c_int_kind)
            {
-             /* The expr needs to be compatible with a C int.  If the 
+             /* The expr needs to be compatible with a C int.  If the
                 conversion fails, then the 2 causes an ICE.  */
              ts.type = BT_INTEGER;
              ts.kind = gfc_c_int_kind;
@@ -2547,8 +2547,8 @@ gfc_add_interface_mapping (gfc_interface_mapping * mapping,
   else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
     value = build_fold_indirect_ref_loc (input_location,
                                     se->expr);
-  
-  /* For character(*), use the actual argument's descriptor.  */  
+
+  /* For character(*), use the actual argument's descriptor.  */
   else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
     value = build_fold_indirect_ref_loc (input_location,
                                     se->expr);
@@ -2958,7 +2958,7 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
   rss = gfc_walk_expr (expr);
 
   gcc_assert (rss != gfc_ss_terminator);
+
   /* Initialize the scalarizer.  */
   gfc_init_loopinfo (&loop);
   gfc_add_ss_to_loop (&loop, rss);
@@ -3118,7 +3118,7 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
 
   tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false, true);
   gfc_add_expr_to_block (&body, tmp);
-  
+
   /* Generate the copying loops.  */
   gfc_trans_scalarizing_loops (&loop2, &body);
 
@@ -3145,7 +3145,7 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
   if (formal_ptr)
     {
       size = gfc_index_one_node;
-      offset = gfc_index_zero_node;  
+      offset = gfc_index_zero_node;
       for (n = 0; n < dimen; n++)
        {
          tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
@@ -3230,7 +3230,7 @@ conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
 {
   gfc_symbol *fsym;
   gfc_ss *argss;
-    
+
   if (sym->intmod_sym_id == ISOCBINDING_LOC)
     {
       if (arg->expr->rank == 0)
@@ -3247,7 +3247,7 @@ conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
            && !(fsym->attr.pointer || fsym->attr.allocatable)
            && fsym->as->type != AS_ASSUMED_SHAPE;
          f = f || !sym->attr.always_explicit;
-      
+
          argss = gfc_walk_expr (arg->expr);
          gfc_conv_array_parameter (se, arg->expr, argss, f,
                                    NULL, NULL, NULL);
@@ -3268,7 +3268,7 @@ conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
       arg->expr->ts.f90_type = sym->ts.u.derived->ts.f90_type;
       arg->expr->ts.kind = sym->ts.u.derived->ts.kind;
       gfc_conv_expr_reference (se, arg->expr);
-  
+
       return 1;
     }
   else if ((sym->intmod_sym_id == ISOCBINDING_F_POINTER
@@ -3293,12 +3293,12 @@ conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
       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 (arg->next->expr->symtree->n.sym->attr.proc_pointer
          && arg->next->expr->symtree->n.sym->attr.dummy)
        fptrse.expr = build_fold_indirect_ref_loc (input_location,
                                                   fptrse.expr);
-      
+
       se->expr = fold_build2_loc (input_location, MODIFY_EXPR,
                                  TREE_TYPE (fptrse.expr),
                                  fptrse.expr,
@@ -3332,7 +3332,7 @@ conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
        {
          tree eq_expr;
          tree not_null_expr;
-         
+
          /* Given two arguments so build the arg2se from second arg.  */
          gfc_init_se (&arg2se, NULL);
          gfc_conv_expr (&arg2se, arg->next->expr);
@@ -3356,7 +3356,7 @@ conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
 
       return 1;
     }
-    
+
   /* Nothing was done.  */
   return 0;
 }
@@ -3536,7 +3536,13 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
                parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
            }
          else
-           gfc_conv_expr_reference (&parmse, e);
+           {
+             gfc_conv_expr_reference (&parmse, e);
+             if (e->ts.type == BT_CHARACTER && !e->rank
+                 && e->expr_type == EXPR_FUNCTION)
+               parmse.expr = build_fold_indirect_ref_loc (input_location,
+                                                          parmse.expr);
+           }
 
          /* The scalarizer does not repackage the reference to a class
             array - instead it returns a pointer to the data element.  */
@@ -3625,7 +3631,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
                      && !CLASS_DATA (e)->attr.codimension)
                    parmse.expr = gfc_class_data_get (parmse.expr);
 
-                 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 
+                 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
                     allocated on entry, it must be deallocated.  */
                  if (fsym && fsym->attr.allocatable
                      && fsym->attr.intent == INTENT_OUT)
@@ -3709,7 +3715,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 
              /* If the argument is a function call that may not create
                 a temporary for the result, we have to check that we
-                can do it, i.e. that there is no alias between this 
+                can do it, i.e. that there is no alias between this
                 argument and another one.  */
              if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
                {
@@ -3770,7 +3776,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
                gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
                                          sym->name, NULL);
 
-             /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 
+             /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
                 allocated on entry, it must be deallocated.  */
              if (fsym && fsym->attr.allocatable
                  && fsym->attr.intent == INTENT_OUT)
@@ -3787,7 +3793,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
                                       tmp, build_empty_stmt (input_location));
                  gfc_add_expr_to_block (&se->pre, tmp);
                }
-           } 
+           }
        }
 
       /* The case with fsym->attr.optional is that of a user subroutine
@@ -3813,7 +3819,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
              && ((e->rank > 0 && sym->attr.elemental)
                  || e->representation.length || e->ts.type == BT_CHARACTER
                  || (e->rank > 0
-                     && (fsym == NULL 
+                     && (fsym == NULL
                          || (fsym-> as
                              && (fsym->as->type == AS_ASSUMED_SHAPE
                                  || fsym->as->type == AS_DEFERRED))))))
@@ -3982,7 +3988,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
                                      fold_convert (TREE_TYPE (tmp),
                                                    null_pointer_node));
            }
+
          gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
                                   msg);
          free (msg);
@@ -4039,7 +4045,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
                          && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
              tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
            }
-         
+
          VEC_safe_push (tree, gc, stringargs, tmp);
 
          if (GFC_DESCRIPTOR_TYPE_P (caf_type)
@@ -4132,7 +4138,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
            gfc_conv_expr (&parmse, ts.u.cl->length);
          gfc_add_block_to_block (&se->pre, &parmse.pre);
          gfc_add_block_to_block (&se->post, &parmse.post);
-         
+
          tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
          tmp = fold_build2_loc (input_location, MAX_EXPR,
                                 gfc_charlen_type_node, tmp,
@@ -4868,7 +4874,7 @@ gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
 
 
 /* Build a static initializer.  EXPR is the expression for the initial value.
-   The other parameters describe the variable of the component being 
+   The other parameters describe the variable of the component being
    initialized. EXPR may be null.  */
 
 tree
@@ -4899,7 +4905,7 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
       gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
       return se.expr;
     }
-  
+
   if (array && !procptr)
     {
       tree ctor;
@@ -4957,7 +4963,7 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
        }
     }
 }
-  
+
 static tree
 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
 {
@@ -5004,7 +5010,7 @@ gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
               cm->as->lower[n]->value.integer);
       mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
     }
-  
+
   /* Associate the SS with the loop.  */
   gfc_add_ss_to_loop (&loop, lss);
   gfc_add_ss_to_loop (&loop, rss);
@@ -5070,7 +5076,7 @@ gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
   gfc_start_block (&block);
   gfc_init_se (&se, NULL);
 
-  /* Get the descriptor for the expressions.  */ 
+  /* Get the descriptor for the expressions.  */
   rss = gfc_walk_expr (expr);
   se.want_pointer = 0;
   gfc_conv_expr_descriptor (&se, expr, rss);
@@ -5325,7 +5331,7 @@ gfc_trans_structure_assign (tree dest, gfc_expr * expr)
                      fold_convert (TREE_TYPE (lse.expr), se.expr));
 
       return gfc_finish_block (&block);
-    } 
+    }
 
   for (c = gfc_constructor_first (expr->value.constructor);
        c; c = gfc_constructor_next (c), cm = cm->next)
@@ -5407,7 +5413,7 @@ gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
        }
     }
   se->expr = build_constructor (type, v);
-  if (init) 
+  if (init)
     TREE_CONSTANT (se->expr) = 1;
 }
 
@@ -5752,7 +5758,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
       for (remap = expr1->ref; remap; remap = remap->next)
        if (!remap->next && remap->type == REF_ARRAY
            && remap->u.ar.type == AR_SECTION)
-         {  
+         {
            remap->u.ar.type = AR_FULL;
            break;
          }
@@ -6050,7 +6056,7 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
   else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
     {
       cond = NULL_TREE;
-       
+
       /* Are the rhs and the lhs the same?  */
       if (r_is_var)
        {
@@ -6146,7 +6152,7 @@ arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
 
   /* Functions returning pointers or allocatables need temporaries.  */
   c = expr2->value.function.esym
-      ? (expr2->value.function.esym->attr.pointer 
+      ? (expr2->value.function.esym->attr.pointer
         || expr2->value.function.esym->attr.allocatable)
       : (expr2->symtree->n.sym->attr.pointer
         || expr2->symtree->n.sym->attr.allocatable);
@@ -6439,7 +6445,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
      correctly take care of the reallocation internally. For intrinsic
      calls, the array data is freed and the library takes care of allocation.
      TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
-     to the library.  */    
+     to the library.  */
   if (gfc_option.flag_realloc_lhs
        && gfc_is_reallocatable_lhs (expr1)
        && !gfc_expr_attr (expr1).codimension
@@ -6713,7 +6719,7 @@ alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
   gfc_init_se (&lse, NULL);
   lse.want_pointer = 1;
   gfc_conv_expr (&lse, expr1);
-  
+
   jump_label1 = gfc_build_label_decl (NULL_TREE);
   jump_label2 = gfc_build_label_decl (NULL_TREE);
 
index 58a7e90..90a0c22 100644 (file)
@@ -1,3 +1,8 @@
+2013-01-13  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/55618
+       * gfortran.dg/elemental_scalar_args_2.f90: New test.
+
 2013-01-08  Mikael Morin  <mikael@gcc.gnu.org>
 
        PR fortran/42769
 
 2012-02-06  Andrey Belevantsev  <abel@ispras.ru>
 
-       * gcc.dg/pr48374.c: Actually add the test I forgot 
+       * gcc.dg/pr48374.c: Actually add the test I forgot
        in the 2012-01-25 commit.
 
 2012-02-05  Thomas König  <tkoenig@gcc.gnu.org>
diff --git a/gcc/testsuite/gfortran.dg/elemental_scalar_args_2.f90 b/gcc/testsuite/gfortran.dg/elemental_scalar_args_2.f90
new file mode 100644 (file)
index 0000000..c2b5df8
--- /dev/null
@@ -0,0 +1,36 @@
+! { dg-do run }
+! Test the fix for PR55618, in which character scalar function arguments to
+! elemental functions would gain an extra indirect reference thus causing
+! failures in Vst17.f95, Vst 30.f95 and Vst31.f95 in the iso_varying_string
+! testsuite, where elemental tests are done.
+!
+! Reported by Tobias Burnus  <burnus@gcc.gnu.org>
+!
+  integer, dimension (2) :: i = [1,2]
+  integer :: j = 64
+  character (len = 2) :: chr1 = "lm"
+  character (len = 1), dimension (2) :: chr2 = ["r", "s"]
+  if (any (foo (i, bar()) .ne. ["a", "b"])) call abort    ! This would fail
+  if (any (foo (i, "xy") .ne. ["x", "y"])) call abort     ! OK - not a function
+  if (any (foo (i, chr1) .ne. ["l", "m"])) call abort     ! ditto
+  if (any (foo (i, char (j)) .ne. ["A", "B"])) call abort ! This would fail
+  if (any (foo (i, chr2) .ne. ["s", "u"])) call abort     ! OK - not a scalar
+  if (any (foo (i, bar2()) .ne. ["e", "g"])) call abort   ! OK - not a scalar function
+contains
+  elemental character(len = 1) function foo (arg1, arg2)
+    integer, intent (in) :: arg1
+    character(len = *), intent (in) :: arg2
+    if (len (arg2) > 1) then
+      foo = arg2(arg1:arg1)
+    else
+      foo = char (ichar (arg2) + arg1)
+    end if
+  end function
+  character(len = 2) function bar ()
+    bar = "ab"
+  end function
+  function bar2 () result(res)
+    character (len = 1), dimension(2) :: res
+    res = ["d", "e"]
+  end function
+end