OSDN Git Service

* configure.ac: Use AC_SEARCH_LIBS to find dlopen.
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-expr.c
1 /* Expression translation
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3    Free Software Foundation, Inc.
4    Contributed by Paul Brook <paul@nowt.org>
5    and Steven Bosscher <s.bosscher@student.tudelft.nl>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 /* trans-expr.c-- generate GENERIC trees for gfc_expr.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tree.h"
29 #include "convert.h"
30 #include "ggc.h"
31 #include "toplev.h"
32 #include "real.h"
33 #include "gimple.h"
34 #include "langhooks.h"
35 #include "flags.h"
36 #include "gfortran.h"
37 #include "arith.h"
38 #include "trans.h"
39 #include "trans-const.h"
40 #include "trans-types.h"
41 #include "trans-array.h"
42 /* Only for gfc_trans_assign and gfc_trans_pointer_assign.  */
43 #include "trans-stmt.h"
44 #include "dependency.h"
45
46 static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
47 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
48                                                  gfc_expr *);
49
50 /* Copy the scalarization loop variables.  */
51
52 static void
53 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
54 {
55   dest->ss = src->ss;
56   dest->loop = src->loop;
57 }
58
59
60 /* Initialize a simple expression holder.
61
62    Care must be taken when multiple se are created with the same parent.
63    The child se must be kept in sync.  The easiest way is to delay creation
64    of a child se until after after the previous se has been translated.  */
65
66 void
67 gfc_init_se (gfc_se * se, gfc_se * parent)
68 {
69   memset (se, 0, sizeof (gfc_se));
70   gfc_init_block (&se->pre);
71   gfc_init_block (&se->post);
72
73   se->parent = parent;
74
75   if (parent)
76     gfc_copy_se_loopvars (se, parent);
77 }
78
79
80 /* Advances to the next SS in the chain.  Use this rather than setting
81    se->ss = se->ss->next because all the parents needs to be kept in sync.
82    See gfc_init_se.  */
83
84 void
85 gfc_advance_se_ss_chain (gfc_se * se)
86 {
87   gfc_se *p;
88
89   gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
90
91   p = se;
92   /* Walk down the parent chain.  */
93   while (p != NULL)
94     {
95       /* Simple consistency check.  */
96       gcc_assert (p->parent == NULL || p->parent->ss == p->ss);
97
98       p->ss = p->ss->next;
99
100       p = p->parent;
101     }
102 }
103
104
105 /* Ensures the result of the expression as either a temporary variable
106    or a constant so that it can be used repeatedly.  */
107
108 void
109 gfc_make_safe_expr (gfc_se * se)
110 {
111   tree var;
112
113   if (CONSTANT_CLASS_P (se->expr))
114     return;
115
116   /* We need a temporary for this result.  */
117   var = gfc_create_var (TREE_TYPE (se->expr), NULL);
118   gfc_add_modify (&se->pre, var, se->expr);
119   se->expr = var;
120 }
121
122
123 /* Return an expression which determines if a dummy parameter is present.
124    Also used for arguments to procedures with multiple entry points.  */
125
126 tree
127 gfc_conv_expr_present (gfc_symbol * sym)
128 {
129   tree decl;
130
131   gcc_assert (sym->attr.dummy);
132
133   decl = gfc_get_symbol_decl (sym);
134   if (TREE_CODE (decl) != PARM_DECL)
135     {
136       /* Array parameters use a temporary descriptor, we want the real
137          parameter.  */
138       gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
139              || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
140       decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
141     }
142   return fold_build2 (NE_EXPR, boolean_type_node, decl,
143                       fold_convert (TREE_TYPE (decl), null_pointer_node));
144 }
145
146
147 /* Converts a missing, dummy argument into a null or zero.  */
148
149 void
150 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
151 {
152   tree present;
153   tree tmp;
154
155   present = gfc_conv_expr_present (arg->symtree->n.sym);
156
157   if (kind > 0)
158     {
159       /* Create a temporary and convert it to the correct type.  */
160       tmp = gfc_get_int_type (kind);
161       tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
162                                                         se->expr));
163     
164       /* Test for a NULL value.  */
165       tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present, tmp,
166                     fold_convert (TREE_TYPE (tmp), integer_one_node));
167       tmp = gfc_evaluate_now (tmp, &se->pre);
168       se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
169     }
170   else
171     {
172       tmp = build3 (COND_EXPR, TREE_TYPE (se->expr), present, se->expr,
173                     fold_convert (TREE_TYPE (se->expr), integer_zero_node));
174       tmp = gfc_evaluate_now (tmp, &se->pre);
175       se->expr = tmp;
176     }
177
178   if (ts.type == BT_CHARACTER)
179     {
180       tmp = build_int_cst (gfc_charlen_type_node, 0);
181       tmp = fold_build3 (COND_EXPR, gfc_charlen_type_node,
182                          present, se->string_length, tmp);
183       tmp = gfc_evaluate_now (tmp, &se->pre);
184       se->string_length = tmp;
185     }
186   return;
187 }
188
189
190 /* Get the character length of an expression, looking through gfc_refs
191    if necessary.  */
192
193 tree
194 gfc_get_expr_charlen (gfc_expr *e)
195 {
196   gfc_ref *r;
197   tree length;
198
199   gcc_assert (e->expr_type == EXPR_VARIABLE 
200               && e->ts.type == BT_CHARACTER);
201   
202   length = NULL; /* To silence compiler warning.  */
203
204   if (is_subref_array (e) && e->ts.u.cl->length)
205     {
206       gfc_se tmpse;
207       gfc_init_se (&tmpse, NULL);
208       gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
209       e->ts.u.cl->backend_decl = tmpse.expr;
210       return tmpse.expr;
211     }
212
213   /* First candidate: if the variable is of type CHARACTER, the
214      expression's length could be the length of the character
215      variable.  */
216   if (e->symtree->n.sym->ts.type == BT_CHARACTER)
217     length = e->symtree->n.sym->ts.u.cl->backend_decl;
218
219   /* Look through the reference chain for component references.  */
220   for (r = e->ref; r; r = r->next)
221     {
222       switch (r->type)
223         {
224         case REF_COMPONENT:
225           if (r->u.c.component->ts.type == BT_CHARACTER)
226             length = r->u.c.component->ts.u.cl->backend_decl;
227           break;
228
229         case REF_ARRAY:
230           /* Do nothing.  */
231           break;
232
233         default:
234           /* We should never got substring references here.  These will be
235              broken down by the scalarizer.  */
236           gcc_unreachable ();
237           break;
238         }
239     }
240
241   gcc_assert (length != NULL);
242   return length;
243 }
244
245
246 /* For each character array constructor subexpression without a ts.u.cl->length,
247    replace it by its first element (if there aren't any elements, the length
248    should already be set to zero).  */
249
250 static void
251 flatten_array_ctors_without_strlen (gfc_expr* e)
252 {
253   gfc_actual_arglist* arg;
254   gfc_constructor* c;
255
256   if (!e)
257     return;
258
259   switch (e->expr_type)
260     {
261
262     case EXPR_OP:
263       flatten_array_ctors_without_strlen (e->value.op.op1); 
264       flatten_array_ctors_without_strlen (e->value.op.op2); 
265       break;
266
267     case EXPR_COMPCALL:
268       /* TODO: Implement as with EXPR_FUNCTION when needed.  */
269       gcc_unreachable ();
270
271     case EXPR_FUNCTION:
272       for (arg = e->value.function.actual; arg; arg = arg->next)
273         flatten_array_ctors_without_strlen (arg->expr);
274       break;
275
276     case EXPR_ARRAY:
277
278       /* We've found what we're looking for.  */
279       if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
280         {
281           gfc_expr* new_expr;
282           gcc_assert (e->value.constructor);
283
284           new_expr = e->value.constructor->expr;
285           e->value.constructor->expr = NULL;
286
287           flatten_array_ctors_without_strlen (new_expr);
288           gfc_replace_expr (e, new_expr);
289           break;
290         }
291
292       /* Otherwise, fall through to handle constructor elements.  */
293     case EXPR_STRUCTURE:
294       for (c = e->value.constructor; c; c = c->next)
295         flatten_array_ctors_without_strlen (c->expr);
296       break;
297
298     default:
299       break;
300
301     }
302 }
303
304
305 /* Generate code to initialize a string length variable. Returns the
306    value.  For array constructors, cl->length might be NULL and in this case,
307    the first element of the constructor is needed.  expr is the original
308    expression so we can access it but can be NULL if this is not needed.  */
309
310 void
311 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
312 {
313   gfc_se se;
314
315   gfc_init_se (&se, NULL);
316
317   /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
318      "flatten" array constructors by taking their first element; all elements
319      should be the same length or a cl->length should be present.  */
320   if (!cl->length)
321     {
322       gfc_expr* expr_flat;
323       gcc_assert (expr);
324
325       expr_flat = gfc_copy_expr (expr);
326       flatten_array_ctors_without_strlen (expr_flat);
327       gfc_resolve_expr (expr_flat);
328
329       gfc_conv_expr (&se, expr_flat);
330       gfc_add_block_to_block (pblock, &se.pre);
331       cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
332
333       gfc_free_expr (expr_flat);
334       return;
335     }
336
337   /* Convert cl->length.  */
338
339   gcc_assert (cl->length);
340
341   gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
342   se.expr = fold_build2 (MAX_EXPR, gfc_charlen_type_node, se.expr,
343                          build_int_cst (gfc_charlen_type_node, 0));
344   gfc_add_block_to_block (pblock, &se.pre);
345
346   if (cl->backend_decl)
347     gfc_add_modify (pblock, cl->backend_decl, se.expr);
348   else
349     cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
350 }
351
352
353 static void
354 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
355                     const char *name, locus *where)
356 {
357   tree tmp;
358   tree type;
359   tree var;
360   tree fault;
361   gfc_se start;
362   gfc_se end;
363   char *msg;
364
365   type = gfc_get_character_type (kind, ref->u.ss.length);
366   type = build_pointer_type (type);
367
368   var = NULL_TREE;
369   gfc_init_se (&start, se);
370   gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
371   gfc_add_block_to_block (&se->pre, &start.pre);
372
373   if (integer_onep (start.expr))
374     gfc_conv_string_parameter (se);
375   else
376     {
377       tmp = start.expr;
378       STRIP_NOPS (tmp);
379       /* Avoid multiple evaluation of substring start.  */
380       if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
381         start.expr = gfc_evaluate_now (start.expr, &se->pre);
382
383       /* Change the start of the string.  */
384       if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
385         tmp = se->expr;
386       else
387         tmp = build_fold_indirect_ref_loc (input_location,
388                                        se->expr);
389       tmp = gfc_build_array_ref (tmp, start.expr, NULL);
390       se->expr = gfc_build_addr_expr (type, tmp);
391     }
392
393   /* Length = end + 1 - start.  */
394   gfc_init_se (&end, se);
395   if (ref->u.ss.end == NULL)
396     end.expr = se->string_length;
397   else
398     {
399       gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
400       gfc_add_block_to_block (&se->pre, &end.pre);
401     }
402   tmp = end.expr;
403   STRIP_NOPS (tmp);
404   if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
405     end.expr = gfc_evaluate_now (end.expr, &se->pre);
406
407   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
408     {
409       tree nonempty = fold_build2 (LE_EXPR, boolean_type_node,
410                                    start.expr, end.expr);
411
412       /* Check lower bound.  */
413       fault = fold_build2 (LT_EXPR, boolean_type_node, start.expr,
414                            build_int_cst (gfc_charlen_type_node, 1));
415       fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
416                            nonempty, fault);
417       if (name)
418         asprintf (&msg, "Substring out of bounds: lower bound (%%ld) of '%s' "
419                   "is less than one", name);
420       else
421         asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
422                   "is less than one");
423       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
424                                fold_convert (long_integer_type_node,
425                                              start.expr));
426       gfc_free (msg);
427
428       /* Check upper bound.  */
429       fault = fold_build2 (GT_EXPR, boolean_type_node, end.expr,
430                            se->string_length);
431       fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
432                            nonempty, fault);
433       if (name)
434         asprintf (&msg, "Substring out of bounds: upper bound (%%ld) of '%s' "
435                   "exceeds string length (%%ld)", name);
436       else
437         asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
438                   "exceeds string length (%%ld)");
439       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
440                                fold_convert (long_integer_type_node, end.expr),
441                                fold_convert (long_integer_type_node,
442                                              se->string_length));
443       gfc_free (msg);
444     }
445
446   tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node,
447                      end.expr, start.expr);
448   tmp = fold_build2 (PLUS_EXPR, gfc_charlen_type_node,
449                      build_int_cst (gfc_charlen_type_node, 1), tmp);
450   tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
451                      build_int_cst (gfc_charlen_type_node, 0));
452   se->string_length = tmp;
453 }
454
455
456 /* Convert a derived type component reference.  */
457
458 static void
459 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
460 {
461   gfc_component *c;
462   tree tmp;
463   tree decl;
464   tree field;
465
466   c = ref->u.c.component;
467
468   gcc_assert (c->backend_decl);
469
470   field = c->backend_decl;
471   gcc_assert (TREE_CODE (field) == FIELD_DECL);
472   decl = se->expr;
473   tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
474
475   se->expr = tmp;
476
477   if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer)
478     {
479       tmp = c->ts.u.cl->backend_decl;
480       /* Components must always be constant length.  */
481       gcc_assert (tmp && INTEGER_CST_P (tmp));
482       se->string_length = tmp;
483     }
484
485   if (((c->attr.pointer || c->attr.allocatable) && c->attr.dimension == 0
486        && c->ts.type != BT_CHARACTER)
487       || c->attr.proc_pointer)
488     se->expr = build_fold_indirect_ref_loc (input_location,
489                                         se->expr);
490 }
491
492
493 /* This function deals with component references to components of the
494    parent type for derived type extensons.  */
495 static void
496 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
497 {
498   gfc_component *c;
499   gfc_component *cmp;
500   gfc_symbol *dt;
501   gfc_ref parent;
502
503   dt = ref->u.c.sym;
504   c = ref->u.c.component;
505
506   /* Build a gfc_ref to recursively call gfc_conv_component_ref.  */
507   parent.type = REF_COMPONENT;
508   parent.next = NULL;
509   parent.u.c.sym = dt;
510   parent.u.c.component = dt->components;
511
512   if (dt->attr.extension && dt->components)
513     {
514       if (dt->attr.is_class)
515         cmp = dt->components;
516       else
517         cmp = dt->components->next;
518       /* Return if the component is not in the parent type.  */
519       for (; cmp; cmp = cmp->next)
520         if (strcmp (c->name, cmp->name) == 0)
521           return;
522         
523       /* Otherwise build the reference and call self.  */
524       gfc_conv_component_ref (se, &parent);
525       parent.u.c.sym = dt->components->ts.u.derived;
526       parent.u.c.component = c;
527       conv_parent_component_references (se, &parent);
528     }
529 }
530
531 /* Return the contents of a variable. Also handles reference/pointer
532    variables (all Fortran pointer references are implicit).  */
533
534 static void
535 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
536 {
537   gfc_ref *ref;
538   gfc_symbol *sym;
539   tree parent_decl;
540   int parent_flag;
541   bool return_value;
542   bool alternate_entry;
543   bool entry_master;
544
545   sym = expr->symtree->n.sym;
546   if (se->ss != NULL)
547     {
548       /* Check that something hasn't gone horribly wrong.  */
549       gcc_assert (se->ss != gfc_ss_terminator);
550       gcc_assert (se->ss->expr == expr);
551
552       /* A scalarized term.  We already know the descriptor.  */
553       se->expr = se->ss->data.info.descriptor;
554       se->string_length = se->ss->string_length;
555       for (ref = se->ss->data.info.ref; ref; ref = ref->next)
556         if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
557           break;
558     }
559   else
560     {
561       tree se_expr = NULL_TREE;
562
563       se->expr = gfc_get_symbol_decl (sym);
564
565       /* Deal with references to a parent results or entries by storing
566          the current_function_decl and moving to the parent_decl.  */
567       return_value = sym->attr.function && sym->result == sym;
568       alternate_entry = sym->attr.function && sym->attr.entry
569                         && sym->result == sym;
570       entry_master = sym->attr.result
571                      && sym->ns->proc_name->attr.entry_master
572                      && !gfc_return_by_reference (sym->ns->proc_name);
573       parent_decl = DECL_CONTEXT (current_function_decl);
574
575       if ((se->expr == parent_decl && return_value)
576            || (sym->ns && sym->ns->proc_name
577                && parent_decl
578                && sym->ns->proc_name->backend_decl == parent_decl
579                && (alternate_entry || entry_master)))
580         parent_flag = 1;
581       else
582         parent_flag = 0;
583
584       /* Special case for assigning the return value of a function.
585          Self recursive functions must have an explicit return value.  */
586       if (return_value && (se->expr == current_function_decl || parent_flag))
587         se_expr = gfc_get_fake_result_decl (sym, parent_flag);
588
589       /* Similarly for alternate entry points.  */
590       else if (alternate_entry 
591                && (sym->ns->proc_name->backend_decl == current_function_decl
592                    || parent_flag))
593         {
594           gfc_entry_list *el = NULL;
595
596           for (el = sym->ns->entries; el; el = el->next)
597             if (sym == el->sym)
598               {
599                 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
600                 break;
601               }
602         }
603
604       else if (entry_master
605                && (sym->ns->proc_name->backend_decl == current_function_decl
606                    || parent_flag))
607         se_expr = gfc_get_fake_result_decl (sym, parent_flag);
608
609       if (se_expr)
610         se->expr = se_expr;
611
612       /* Procedure actual arguments.  */
613       else if (sym->attr.flavor == FL_PROCEDURE
614                && se->expr != current_function_decl)
615         {
616           if (!sym->attr.dummy && !sym->attr.proc_pointer)
617             {
618               gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
619               se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
620             }
621           return;
622         }
623
624
625       /* Dereference the expression, where needed. Since characters
626          are entirely different from other types, they are treated 
627          separately.  */
628       if (sym->ts.type == BT_CHARACTER)
629         {
630           /* Dereference character pointer dummy arguments
631              or results.  */
632           if ((sym->attr.pointer || sym->attr.allocatable)
633               && (sym->attr.dummy
634                   || sym->attr.function
635                   || sym->attr.result))
636             se->expr = build_fold_indirect_ref_loc (input_location,
637                                                 se->expr);
638
639         }
640       else if (!sym->attr.value)
641         {
642           /* Dereference non-character scalar dummy arguments.  */
643           if (sym->attr.dummy && !sym->attr.dimension)
644             se->expr = build_fold_indirect_ref_loc (input_location,
645                                                 se->expr);
646
647           /* Dereference scalar hidden result.  */
648           if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
649               && (sym->attr.function || sym->attr.result)
650               && !sym->attr.dimension && !sym->attr.pointer
651               && !sym->attr.always_explicit)
652             se->expr = build_fold_indirect_ref_loc (input_location,
653                                                 se->expr);
654
655           /* Dereference non-character pointer variables. 
656              These must be dummies, results, or scalars.  */
657           if ((sym->attr.pointer || sym->attr.allocatable)
658               && (sym->attr.dummy
659                   || sym->attr.function
660                   || sym->attr.result
661                   || !sym->attr.dimension))
662             se->expr = build_fold_indirect_ref_loc (input_location,
663                                                 se->expr);
664         }
665
666       ref = expr->ref;
667     }
668
669   /* For character variables, also get the length.  */
670   if (sym->ts.type == BT_CHARACTER)
671     {
672       /* If the character length of an entry isn't set, get the length from
673          the master function instead.  */
674       if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
675         se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
676       else
677         se->string_length = sym->ts.u.cl->backend_decl;
678       gcc_assert (se->string_length);
679     }
680
681   while (ref)
682     {
683       switch (ref->type)
684         {
685         case REF_ARRAY:
686           /* Return the descriptor if that's what we want and this is an array
687              section reference.  */
688           if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
689             return;
690 /* TODO: Pointers to single elements of array sections, eg elemental subs.  */
691           /* Return the descriptor for array pointers and allocations.  */
692           if (se->want_pointer
693               && ref->next == NULL && (se->descriptor_only))
694             return;
695
696           gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
697           /* Return a pointer to an element.  */
698           break;
699
700         case REF_COMPONENT:
701           if (ref->u.c.sym->attr.extension)
702             conv_parent_component_references (se, ref);
703
704           gfc_conv_component_ref (se, ref);
705           break;
706
707         case REF_SUBSTRING:
708           gfc_conv_substring (se, ref, expr->ts.kind,
709                               expr->symtree->name, &expr->where);
710           break;
711
712         default:
713           gcc_unreachable ();
714           break;
715         }
716       ref = ref->next;
717     }
718   /* Pointer assignment, allocation or pass by reference.  Arrays are handled
719      separately.  */
720   if (se->want_pointer)
721     {
722       if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr, NULL))
723         gfc_conv_string_parameter (se);
724       else 
725         se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
726     }
727 }
728
729
730 /* Unary ops are easy... Or they would be if ! was a valid op.  */
731
732 static void
733 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
734 {
735   gfc_se operand;
736   tree type;
737
738   gcc_assert (expr->ts.type != BT_CHARACTER);
739   /* Initialize the operand.  */
740   gfc_init_se (&operand, se);
741   gfc_conv_expr_val (&operand, expr->value.op.op1);
742   gfc_add_block_to_block (&se->pre, &operand.pre);
743
744   type = gfc_typenode_for_spec (&expr->ts);
745
746   /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
747      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
748      All other unary operators have an equivalent GIMPLE unary operator.  */
749   if (code == TRUTH_NOT_EXPR)
750     se->expr = fold_build2 (EQ_EXPR, type, operand.expr,
751                             build_int_cst (type, 0));
752   else
753     se->expr = fold_build1 (code, type, operand.expr);
754
755 }
756
757 /* Expand power operator to optimal multiplications when a value is raised
758    to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
759    Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
760    Programming", 3rd Edition, 1998.  */
761
762 /* This code is mostly duplicated from expand_powi in the backend.
763    We establish the "optimal power tree" lookup table with the defined size.
764    The items in the table are the exponents used to calculate the index
765    exponents. Any integer n less than the value can get an "addition chain",
766    with the first node being one.  */
767 #define POWI_TABLE_SIZE 256
768
769 /* The table is from builtins.c.  */
770 static const unsigned char powi_table[POWI_TABLE_SIZE] =
771   {
772       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
773       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
774       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
775      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
776      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
777      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
778      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
779      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
780      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
781      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
782      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
783      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
784      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
785      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
786      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
787      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
788      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
789      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
790      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
791      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
792      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
793      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
794      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
795      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
796      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
797     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
798     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
799     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
800     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
801     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
802     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
803     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
804   };
805
806 /* If n is larger than lookup table's max index, we use the "window 
807    method".  */
808 #define POWI_WINDOW_SIZE 3
809
810 /* Recursive function to expand the power operator. The temporary 
811    values are put in tmpvar. The function returns tmpvar[1] ** n.  */
812 static tree
813 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
814 {
815   tree op0;
816   tree op1;
817   tree tmp;
818   int digit;
819
820   if (n < POWI_TABLE_SIZE)
821     {
822       if (tmpvar[n])
823         return tmpvar[n];
824
825       op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
826       op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
827     }
828   else if (n & 1)
829     {
830       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
831       op0 = gfc_conv_powi (se, n - digit, tmpvar);
832       op1 = gfc_conv_powi (se, digit, tmpvar);
833     }
834   else
835     {
836       op0 = gfc_conv_powi (se, n >> 1, tmpvar);
837       op1 = op0;
838     }
839
840   tmp = fold_build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1);
841   tmp = gfc_evaluate_now (tmp, &se->pre);
842
843   if (n < POWI_TABLE_SIZE)
844     tmpvar[n] = tmp;
845
846   return tmp;
847 }
848
849
850 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
851    return 1. Else return 0 and a call to runtime library functions
852    will have to be built.  */
853 static int
854 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
855 {
856   tree cond;
857   tree tmp;
858   tree type;
859   tree vartmp[POWI_TABLE_SIZE];
860   HOST_WIDE_INT m;
861   unsigned HOST_WIDE_INT n;
862   int sgn;
863
864   /* If exponent is too large, we won't expand it anyway, so don't bother
865      with large integer values.  */
866   if (!double_int_fits_in_shwi_p (TREE_INT_CST (rhs)))
867     return 0;
868
869   m = double_int_to_shwi (TREE_INT_CST (rhs));
870   /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
871      of the asymmetric range of the integer type.  */
872   n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
873   
874   type = TREE_TYPE (lhs);
875   sgn = tree_int_cst_sgn (rhs);
876
877   if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
878        || optimize_size) && (m > 2 || m < -1))
879     return 0;
880
881   /* rhs == 0  */
882   if (sgn == 0)
883     {
884       se->expr = gfc_build_const (type, integer_one_node);
885       return 1;
886     }
887
888   /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1.  */
889   if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
890     {
891       tmp = fold_build2 (EQ_EXPR, boolean_type_node,
892                          lhs, build_int_cst (TREE_TYPE (lhs), -1));
893       cond = fold_build2 (EQ_EXPR, boolean_type_node,
894                           lhs, build_int_cst (TREE_TYPE (lhs), 1));
895
896       /* If rhs is even,
897          result = (lhs == 1 || lhs == -1) ? 1 : 0.  */
898       if ((n & 1) == 0)
899         {
900           tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
901           se->expr = fold_build3 (COND_EXPR, type,
902                                   tmp, build_int_cst (type, 1),
903                                   build_int_cst (type, 0));
904           return 1;
905         }
906       /* If rhs is odd,
907          result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0.  */
908       tmp = fold_build3 (COND_EXPR, type, tmp, build_int_cst (type, -1),
909                          build_int_cst (type, 0));
910       se->expr = fold_build3 (COND_EXPR, type,
911                               cond, build_int_cst (type, 1), tmp);
912       return 1;
913     }
914
915   memset (vartmp, 0, sizeof (vartmp));
916   vartmp[1] = lhs;
917   if (sgn == -1)
918     {
919       tmp = gfc_build_const (type, integer_one_node);
920       vartmp[1] = fold_build2 (RDIV_EXPR, type, tmp, vartmp[1]);
921     }
922
923   se->expr = gfc_conv_powi (se, n, vartmp);
924
925   return 1;
926 }
927
928
929 /* Power op (**).  Constant integer exponent has special handling.  */
930
931 static void
932 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
933 {
934   tree gfc_int4_type_node;
935   int kind;
936   int ikind;
937   gfc_se lse;
938   gfc_se rse;
939   tree fndecl;
940
941   gfc_init_se (&lse, se);
942   gfc_conv_expr_val (&lse, expr->value.op.op1);
943   lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
944   gfc_add_block_to_block (&se->pre, &lse.pre);
945
946   gfc_init_se (&rse, se);
947   gfc_conv_expr_val (&rse, expr->value.op.op2);
948   gfc_add_block_to_block (&se->pre, &rse.pre);
949
950   if (expr->value.op.op2->ts.type == BT_INTEGER
951       && expr->value.op.op2->expr_type == EXPR_CONSTANT)
952     if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
953       return;
954
955   gfc_int4_type_node = gfc_get_int_type (4);
956
957   kind = expr->value.op.op1->ts.kind;
958   switch (expr->value.op.op2->ts.type)
959     {
960     case BT_INTEGER:
961       ikind = expr->value.op.op2->ts.kind;
962       switch (ikind)
963         {
964         case 1:
965         case 2:
966           rse.expr = convert (gfc_int4_type_node, rse.expr);
967           /* Fall through.  */
968
969         case 4:
970           ikind = 0;
971           break;
972           
973         case 8:
974           ikind = 1;
975           break;
976
977         case 16:
978           ikind = 2;
979           break;
980
981         default:
982           gcc_unreachable ();
983         }
984       switch (kind)
985         {
986         case 1:
987         case 2:
988           if (expr->value.op.op1->ts.type == BT_INTEGER)
989             lse.expr = convert (gfc_int4_type_node, lse.expr);
990           else
991             gcc_unreachable ();
992           /* Fall through.  */
993
994         case 4:
995           kind = 0;
996           break;
997           
998         case 8:
999           kind = 1;
1000           break;
1001
1002         case 10:
1003           kind = 2;
1004           break;
1005
1006         case 16:
1007           kind = 3;
1008           break;
1009
1010         default:
1011           gcc_unreachable ();
1012         }
1013       
1014       switch (expr->value.op.op1->ts.type)
1015         {
1016         case BT_INTEGER:
1017           if (kind == 3) /* Case 16 was not handled properly above.  */
1018             kind = 2;
1019           fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
1020           break;
1021
1022         case BT_REAL:
1023           /* Use builtins for real ** int4.  */
1024           if (ikind == 0)
1025             {
1026               switch (kind)
1027                 {
1028                 case 0:
1029                   fndecl = built_in_decls[BUILT_IN_POWIF];
1030                   break;
1031                 
1032                 case 1:
1033                   fndecl = built_in_decls[BUILT_IN_POWI];
1034                   break;
1035
1036                 case 2:
1037                 case 3:
1038                   fndecl = built_in_decls[BUILT_IN_POWIL];
1039                   break;
1040
1041                 default:
1042                   gcc_unreachable ();
1043                 }
1044             }
1045           else
1046             fndecl = gfor_fndecl_math_powi[kind][ikind].real;
1047           break;
1048
1049         case BT_COMPLEX:
1050           fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
1051           break;
1052
1053         default:
1054           gcc_unreachable ();
1055         }
1056       break;
1057
1058     case BT_REAL:
1059       switch (kind)
1060         {
1061         case 4:
1062           fndecl = built_in_decls[BUILT_IN_POWF];
1063           break;
1064         case 8:
1065           fndecl = built_in_decls[BUILT_IN_POW];
1066           break;
1067         case 10:
1068         case 16:
1069           fndecl = built_in_decls[BUILT_IN_POWL];
1070           break;
1071         default:
1072           gcc_unreachable ();
1073         }
1074       break;
1075
1076     case BT_COMPLEX:
1077       switch (kind)
1078         {
1079         case 4:
1080           fndecl = built_in_decls[BUILT_IN_CPOWF];
1081           break;
1082         case 8:
1083           fndecl = built_in_decls[BUILT_IN_CPOW];
1084           break;
1085         case 10:
1086         case 16:
1087           fndecl = built_in_decls[BUILT_IN_CPOWL];
1088           break;
1089         default:
1090           gcc_unreachable ();
1091         }
1092       break;
1093
1094     default:
1095       gcc_unreachable ();
1096       break;
1097     }
1098
1099   se->expr = build_call_expr_loc (input_location,
1100                               fndecl, 2, lse.expr, rse.expr);
1101 }
1102
1103
1104 /* Generate code to allocate a string temporary.  */
1105
1106 tree
1107 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
1108 {
1109   tree var;
1110   tree tmp;
1111
1112   gcc_assert (types_compatible_p (TREE_TYPE (len), gfc_charlen_type_node));
1113
1114   if (gfc_can_put_var_on_stack (len))
1115     {
1116       /* Create a temporary variable to hold the result.  */
1117       tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
1118                          build_int_cst (gfc_charlen_type_node, 1));
1119       tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
1120
1121       if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
1122         tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
1123       else
1124         tmp = build_array_type (TREE_TYPE (type), tmp);
1125
1126       var = gfc_create_var (tmp, "str");
1127       var = gfc_build_addr_expr (type, var);
1128     }
1129   else
1130     {
1131       /* Allocate a temporary to hold the result.  */
1132       var = gfc_create_var (type, "pstr");
1133       tmp = gfc_call_malloc (&se->pre, type,
1134                              fold_build2 (MULT_EXPR, TREE_TYPE (len), len,
1135                                           fold_convert (TREE_TYPE (len),
1136                                                         TYPE_SIZE (type))));
1137       gfc_add_modify (&se->pre, var, tmp);
1138
1139       /* Free the temporary afterwards.  */
1140       tmp = gfc_call_free (convert (pvoid_type_node, var));
1141       gfc_add_expr_to_block (&se->post, tmp);
1142     }
1143
1144   return var;
1145 }
1146
1147
1148 /* Handle a string concatenation operation.  A temporary will be allocated to
1149    hold the result.  */
1150
1151 static void
1152 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
1153 {
1154   gfc_se lse, rse;
1155   tree len, type, var, tmp, fndecl;
1156
1157   gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
1158               && expr->value.op.op2->ts.type == BT_CHARACTER);
1159   gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
1160
1161   gfc_init_se (&lse, se);
1162   gfc_conv_expr (&lse, expr->value.op.op1);
1163   gfc_conv_string_parameter (&lse);
1164   gfc_init_se (&rse, se);
1165   gfc_conv_expr (&rse, expr->value.op.op2);
1166   gfc_conv_string_parameter (&rse);
1167
1168   gfc_add_block_to_block (&se->pre, &lse.pre);
1169   gfc_add_block_to_block (&se->pre, &rse.pre);
1170
1171   type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
1172   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1173   if (len == NULL_TREE)
1174     {
1175       len = fold_build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
1176                          lse.string_length, rse.string_length);
1177     }
1178
1179   type = build_pointer_type (type);
1180
1181   var = gfc_conv_string_tmp (se, type, len);
1182
1183   /* Do the actual concatenation.  */
1184   if (expr->ts.kind == 1)
1185     fndecl = gfor_fndecl_concat_string;
1186   else if (expr->ts.kind == 4)
1187     fndecl = gfor_fndecl_concat_string_char4;
1188   else
1189     gcc_unreachable ();
1190
1191   tmp = build_call_expr_loc (input_location,
1192                          fndecl, 6, len, var, lse.string_length, lse.expr,
1193                          rse.string_length, rse.expr);
1194   gfc_add_expr_to_block (&se->pre, tmp);
1195
1196   /* Add the cleanup for the operands.  */
1197   gfc_add_block_to_block (&se->pre, &rse.post);
1198   gfc_add_block_to_block (&se->pre, &lse.post);
1199
1200   se->expr = var;
1201   se->string_length = len;
1202 }
1203
1204 /* Translates an op expression. Common (binary) cases are handled by this
1205    function, others are passed on. Recursion is used in either case.
1206    We use the fact that (op1.ts == op2.ts) (except for the power
1207    operator **).
1208    Operators need no special handling for scalarized expressions as long as
1209    they call gfc_conv_simple_val to get their operands.
1210    Character strings get special handling.  */
1211
1212 static void
1213 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
1214 {
1215   enum tree_code code;
1216   gfc_se lse;
1217   gfc_se rse;
1218   tree tmp, type;
1219   int lop;
1220   int checkstring;
1221
1222   checkstring = 0;
1223   lop = 0;
1224   switch (expr->value.op.op)
1225     {
1226     case INTRINSIC_PARENTHESES:
1227       if (expr->ts.type == BT_REAL
1228           || expr->ts.type == BT_COMPLEX)
1229         {
1230           gfc_conv_unary_op (PAREN_EXPR, se, expr);
1231           gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
1232           return;
1233         }
1234
1235       /* Fallthrough.  */
1236     case INTRINSIC_UPLUS:
1237       gfc_conv_expr (se, expr->value.op.op1);
1238       return;
1239
1240     case INTRINSIC_UMINUS:
1241       gfc_conv_unary_op (NEGATE_EXPR, se, expr);
1242       return;
1243
1244     case INTRINSIC_NOT:
1245       gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
1246       return;
1247
1248     case INTRINSIC_PLUS:
1249       code = PLUS_EXPR;
1250       break;
1251
1252     case INTRINSIC_MINUS:
1253       code = MINUS_EXPR;
1254       break;
1255
1256     case INTRINSIC_TIMES:
1257       code = MULT_EXPR;
1258       break;
1259
1260     case INTRINSIC_DIVIDE:
1261       /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1262          an integer, we must round towards zero, so we use a
1263          TRUNC_DIV_EXPR.  */
1264       if (expr->ts.type == BT_INTEGER)
1265         code = TRUNC_DIV_EXPR;
1266       else
1267         code = RDIV_EXPR;
1268       break;
1269
1270     case INTRINSIC_POWER:
1271       gfc_conv_power_op (se, expr);
1272       return;
1273
1274     case INTRINSIC_CONCAT:
1275       gfc_conv_concat_op (se, expr);
1276       return;
1277
1278     case INTRINSIC_AND:
1279       code = TRUTH_ANDIF_EXPR;
1280       lop = 1;
1281       break;
1282
1283     case INTRINSIC_OR:
1284       code = TRUTH_ORIF_EXPR;
1285       lop = 1;
1286       break;
1287
1288       /* EQV and NEQV only work on logicals, but since we represent them
1289          as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
1290     case INTRINSIC_EQ:
1291     case INTRINSIC_EQ_OS:
1292     case INTRINSIC_EQV:
1293       code = EQ_EXPR;
1294       checkstring = 1;
1295       lop = 1;
1296       break;
1297
1298     case INTRINSIC_NE:
1299     case INTRINSIC_NE_OS:
1300     case INTRINSIC_NEQV:
1301       code = NE_EXPR;
1302       checkstring = 1;
1303       lop = 1;
1304       break;
1305
1306     case INTRINSIC_GT:
1307     case INTRINSIC_GT_OS:
1308       code = GT_EXPR;
1309       checkstring = 1;
1310       lop = 1;
1311       break;
1312
1313     case INTRINSIC_GE:
1314     case INTRINSIC_GE_OS:
1315       code = GE_EXPR;
1316       checkstring = 1;
1317       lop = 1;
1318       break;
1319
1320     case INTRINSIC_LT:
1321     case INTRINSIC_LT_OS:
1322       code = LT_EXPR;
1323       checkstring = 1;
1324       lop = 1;
1325       break;
1326
1327     case INTRINSIC_LE:
1328     case INTRINSIC_LE_OS:
1329       code = LE_EXPR;
1330       checkstring = 1;
1331       lop = 1;
1332       break;
1333
1334     case INTRINSIC_USER:
1335     case INTRINSIC_ASSIGN:
1336       /* These should be converted into function calls by the frontend.  */
1337       gcc_unreachable ();
1338
1339     default:
1340       fatal_error ("Unknown intrinsic op");
1341       return;
1342     }
1343
1344   /* The only exception to this is **, which is handled separately anyway.  */
1345   gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
1346
1347   if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
1348     checkstring = 0;
1349
1350   /* lhs */
1351   gfc_init_se (&lse, se);
1352   gfc_conv_expr (&lse, expr->value.op.op1);
1353   gfc_add_block_to_block (&se->pre, &lse.pre);
1354
1355   /* rhs */
1356   gfc_init_se (&rse, se);
1357   gfc_conv_expr (&rse, expr->value.op.op2);
1358   gfc_add_block_to_block (&se->pre, &rse.pre);
1359
1360   if (checkstring)
1361     {
1362       gfc_conv_string_parameter (&lse);
1363       gfc_conv_string_parameter (&rse);
1364
1365       lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
1366                                            rse.string_length, rse.expr,
1367                                            expr->value.op.op1->ts.kind);
1368       rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
1369       gfc_add_block_to_block (&lse.post, &rse.post);
1370     }
1371
1372   type = gfc_typenode_for_spec (&expr->ts);
1373
1374   if (lop)
1375     {
1376       /* The result of logical ops is always boolean_type_node.  */
1377       tmp = fold_build2 (code, boolean_type_node, lse.expr, rse.expr);
1378       se->expr = convert (type, tmp);
1379     }
1380   else
1381     se->expr = fold_build2 (code, type, lse.expr, rse.expr);
1382
1383   /* Add the post blocks.  */
1384   gfc_add_block_to_block (&se->post, &rse.post);
1385   gfc_add_block_to_block (&se->post, &lse.post);
1386 }
1387
1388 /* If a string's length is one, we convert it to a single character.  */
1389
1390 static tree
1391 string_to_single_character (tree len, tree str, int kind)
1392 {
1393   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
1394
1395   if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
1396       && TREE_INT_CST_HIGH (len) == 0)
1397     {
1398       str = fold_convert (gfc_get_pchar_type (kind), str);
1399       return build_fold_indirect_ref_loc (input_location,
1400                                       str);
1401     }
1402
1403   return NULL_TREE;
1404 }
1405
1406
1407 void
1408 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
1409 {
1410
1411   if (sym->backend_decl)
1412     {
1413       /* This becomes the nominal_type in
1414          function.c:assign_parm_find_data_types.  */
1415       TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
1416       /* This becomes the passed_type in
1417          function.c:assign_parm_find_data_types.  C promotes char to
1418          integer for argument passing.  */
1419       DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
1420
1421       DECL_BY_REFERENCE (sym->backend_decl) = 0;
1422     }
1423
1424   if (expr != NULL)
1425     {
1426       /* If we have a constant character expression, make it into an
1427          integer.  */
1428       if ((*expr)->expr_type == EXPR_CONSTANT)
1429         {
1430           gfc_typespec ts;
1431           gfc_clear_ts (&ts);
1432
1433           *expr = gfc_int_expr ((int)(*expr)->value.character.string[0]);
1434           if ((*expr)->ts.kind != gfc_c_int_kind)
1435             {
1436               /* The expr needs to be compatible with a C int.  If the 
1437                  conversion fails, then the 2 causes an ICE.  */
1438               ts.type = BT_INTEGER;
1439               ts.kind = gfc_c_int_kind;
1440               gfc_convert_type (*expr, &ts, 2);
1441             }
1442         }
1443       else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
1444         {
1445           if ((*expr)->ref == NULL)
1446             {
1447               se->expr = string_to_single_character
1448                 (build_int_cst (integer_type_node, 1),
1449                  gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
1450                                       gfc_get_symbol_decl
1451                                       ((*expr)->symtree->n.sym)),
1452                  (*expr)->ts.kind);
1453             }
1454           else
1455             {
1456               gfc_conv_variable (se, *expr);
1457               se->expr = string_to_single_character
1458                 (build_int_cst (integer_type_node, 1),
1459                  gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
1460                                       se->expr),
1461                  (*expr)->ts.kind);
1462             }
1463         }
1464     }
1465 }
1466
1467
1468 /* Compare two strings. If they are all single characters, the result is the
1469    subtraction of them. Otherwise, we build a library call.  */
1470
1471 tree
1472 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind)
1473 {
1474   tree sc1;
1475   tree sc2;
1476   tree tmp;
1477
1478   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
1479   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
1480
1481   sc1 = string_to_single_character (len1, str1, kind);
1482   sc2 = string_to_single_character (len2, str2, kind);
1483
1484   if (sc1 != NULL_TREE && sc2 != NULL_TREE)
1485     {
1486       /* Deal with single character specially.  */
1487       sc1 = fold_convert (integer_type_node, sc1);
1488       sc2 = fold_convert (integer_type_node, sc2);
1489       tmp = fold_build2 (MINUS_EXPR, integer_type_node, sc1, sc2);
1490     }
1491   else
1492     {
1493       /* Build a call for the comparison.  */
1494       tree fndecl;
1495
1496       if (kind == 1)
1497         fndecl = gfor_fndecl_compare_string;
1498       else if (kind == 4)
1499         fndecl = gfor_fndecl_compare_string_char4;
1500       else
1501         gcc_unreachable ();
1502
1503       tmp = build_call_expr_loc (input_location,
1504                              fndecl, 4, len1, str1, len2, str2);
1505     }
1506
1507   return tmp;
1508 }
1509
1510
1511 /* Return the backend_decl for a procedure pointer component.  */
1512
1513 static tree
1514 get_proc_ptr_comp (gfc_expr *e)
1515 {
1516   gfc_se comp_se;
1517   gfc_expr *e2;
1518   gfc_init_se (&comp_se, NULL);
1519   e2 = gfc_copy_expr (e);
1520   e2->expr_type = EXPR_VARIABLE;
1521   gfc_conv_expr (&comp_se, e2);
1522   return build_fold_addr_expr_loc (input_location, comp_se.expr);
1523 }
1524
1525
1526 /* Select a class typebound procedure at runtime.  */
1527 static void
1528 select_class_proc (gfc_se *se, gfc_class_esym_list *elist,
1529                    tree declared, locus *where)
1530 {
1531   tree end_label;
1532   tree label;
1533   tree tmp;
1534   tree vindex;
1535   stmtblock_t body;
1536   gfc_class_esym_list *next_elist, *tmp_elist;
1537
1538   /* Calculate the switch expression: class_object.vindex.  */
1539   gcc_assert (elist->class_object->ts.type == BT_CLASS);
1540   tmp = elist->class_object->ts.u.derived->components->next->backend_decl;
1541   vindex = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
1542                         elist->class_object->backend_decl,
1543                         tmp, NULL_TREE);
1544   vindex = gfc_evaluate_now (vindex, &se->pre);
1545
1546   /* Fix the function type to be that of the declared type.  */
1547   declared = gfc_create_var (TREE_TYPE (declared), "method");
1548
1549   end_label = gfc_build_label_decl (NULL_TREE);
1550
1551   gfc_init_block (&body);
1552
1553   /* Go through the list of extensions.  */
1554   for (; elist; elist = next_elist)
1555     {
1556       /* This case has already been added.  */
1557       if (elist->derived == NULL)
1558         goto free_elist;
1559
1560       /* Run through the chain picking up all the cases that call the
1561          same procedure.  */
1562       tmp_elist = elist;
1563       for (; elist; elist = elist->next)
1564         {
1565           tree cval;
1566
1567           if (elist->esym != tmp_elist->esym)
1568             continue;
1569
1570           cval = build_int_cst (TREE_TYPE (vindex),
1571                                 elist->derived->vindex);
1572           /* Build a label for the vindex value.  */
1573           label = gfc_build_label_decl (NULL_TREE);
1574           tmp = fold_build3 (CASE_LABEL_EXPR, void_type_node,
1575                              cval, NULL_TREE, label);
1576           gfc_add_expr_to_block (&body, tmp);
1577
1578           /* Null the reference the derived type so that this case is
1579              not used again.  */
1580           elist->derived = NULL;
1581         }
1582
1583       elist = tmp_elist;
1584
1585       /* Get a pointer to the procedure,  */
1586       tmp = gfc_get_symbol_decl (elist->esym);
1587       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1588         {
1589           gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1590           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1591         }
1592
1593       /* Assign the pointer to the appropriate procedure.  */
1594       gfc_add_modify (&body, declared,
1595                       fold_convert (TREE_TYPE (declared), tmp));
1596
1597       /* Break to the end of the construct.  */
1598       tmp = build1_v (GOTO_EXPR, end_label);
1599       gfc_add_expr_to_block (&body, tmp);
1600
1601       /* Free the elists as we go; freeing them in gfc_free_expr causes
1602          segfaults because it occurs too early and too often.  */
1603     free_elist:
1604       next_elist = elist->next;
1605       gfc_free (elist);
1606       elist = NULL;
1607     }
1608
1609   /* Default is an error.  */
1610   label = gfc_build_label_decl (NULL_TREE);
1611   tmp = fold_build3 (CASE_LABEL_EXPR, void_type_node,
1612                      NULL_TREE, NULL_TREE, label);
1613   gfc_add_expr_to_block (&body, tmp);
1614   tmp = gfc_trans_runtime_error (true, where,
1615                 "internal error: bad vindex in dynamic dispatch");
1616   gfc_add_expr_to_block (&body, tmp);
1617
1618   /* Write the switch expression.  */
1619   tmp = gfc_finish_block (&body);
1620   tmp = build3_v (SWITCH_EXPR, vindex, tmp, NULL_TREE);
1621   gfc_add_expr_to_block (&se->pre, tmp);
1622
1623   tmp = build1_v (LABEL_EXPR, end_label);
1624   gfc_add_expr_to_block (&se->pre, tmp);
1625
1626   se->expr = declared;
1627   return;
1628 }
1629
1630
1631 static void
1632 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
1633 {
1634   tree tmp;
1635
1636   if (expr && expr->symtree
1637         && expr->value.function.class_esym)
1638     {
1639       if (!sym->backend_decl)
1640         sym->backend_decl = gfc_get_extern_function_decl (sym);
1641
1642       tmp = sym->backend_decl;
1643
1644       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1645         {
1646           gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1647           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1648         }
1649
1650       select_class_proc (se, expr->value.function.class_esym,
1651                          tmp, &expr->where);
1652       return;
1653     }
1654
1655   if (gfc_is_proc_ptr_comp (expr, NULL))
1656     tmp = get_proc_ptr_comp (expr);
1657   else if (sym->attr.dummy)
1658     {
1659       tmp = gfc_get_symbol_decl (sym);
1660       if (sym->attr.proc_pointer)
1661         tmp = build_fold_indirect_ref_loc (input_location,
1662                                        tmp);
1663       gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1664               && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
1665     }
1666   else
1667     {
1668       if (!sym->backend_decl)
1669         sym->backend_decl = gfc_get_extern_function_decl (sym);
1670
1671       tmp = sym->backend_decl;
1672
1673       if (sym->attr.cray_pointee)
1674         {
1675           /* TODO - make the cray pointee a pointer to a procedure,
1676              assign the pointer to it and use it for the call.  This
1677              will do for now!  */
1678           tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
1679                          gfc_get_symbol_decl (sym->cp_pointer));
1680           tmp = gfc_evaluate_now (tmp, &se->pre);
1681         }
1682
1683       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1684         {
1685           gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1686           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1687         }
1688     }
1689   se->expr = tmp;
1690 }
1691
1692
1693 /* Initialize MAPPING.  */
1694
1695 void
1696 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
1697 {
1698   mapping->syms = NULL;
1699   mapping->charlens = NULL;
1700 }
1701
1702
1703 /* Free all memory held by MAPPING (but not MAPPING itself).  */
1704
1705 void
1706 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
1707 {
1708   gfc_interface_sym_mapping *sym;
1709   gfc_interface_sym_mapping *nextsym;
1710   gfc_charlen *cl;
1711   gfc_charlen *nextcl;
1712
1713   for (sym = mapping->syms; sym; sym = nextsym)
1714     {
1715       nextsym = sym->next;
1716       sym->new_sym->n.sym->formal = NULL;
1717       gfc_free_symbol (sym->new_sym->n.sym);
1718       gfc_free_expr (sym->expr);
1719       gfc_free (sym->new_sym);
1720       gfc_free (sym);
1721     }
1722   for (cl = mapping->charlens; cl; cl = nextcl)
1723     {
1724       nextcl = cl->next;
1725       gfc_free_expr (cl->length);
1726       gfc_free (cl);
1727     }
1728 }
1729
1730
1731 /* Return a copy of gfc_charlen CL.  Add the returned structure to
1732    MAPPING so that it will be freed by gfc_free_interface_mapping.  */
1733
1734 static gfc_charlen *
1735 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
1736                                    gfc_charlen * cl)
1737 {
1738   gfc_charlen *new_charlen;
1739
1740   new_charlen = gfc_get_charlen ();
1741   new_charlen->next = mapping->charlens;
1742   new_charlen->length = gfc_copy_expr (cl->length);
1743
1744   mapping->charlens = new_charlen;
1745   return new_charlen;
1746 }
1747
1748
1749 /* A subroutine of gfc_add_interface_mapping.  Return a descriptorless
1750    array variable that can be used as the actual argument for dummy
1751    argument SYM.  Add any initialization code to BLOCK.  PACKED is as
1752    for gfc_get_nodesc_array_type and DATA points to the first element
1753    in the passed array.  */
1754
1755 static tree
1756 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
1757                                  gfc_packed packed, tree data)
1758 {
1759   tree type;
1760   tree var;
1761
1762   type = gfc_typenode_for_spec (&sym->ts);
1763   type = gfc_get_nodesc_array_type (type, sym->as, packed,
1764                                     !sym->attr.target && !sym->attr.pointer
1765                                     && !sym->attr.proc_pointer);
1766
1767   var = gfc_create_var (type, "ifm");
1768   gfc_add_modify (block, var, fold_convert (type, data));
1769
1770   return var;
1771 }
1772
1773
1774 /* A subroutine of gfc_add_interface_mapping.  Set the stride, upper bounds
1775    and offset of descriptorless array type TYPE given that it has the same
1776    size as DESC.  Add any set-up code to BLOCK.  */
1777
1778 static void
1779 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
1780 {
1781   int n;
1782   tree dim;
1783   tree offset;
1784   tree tmp;
1785
1786   offset = gfc_index_zero_node;
1787   for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
1788     {
1789       dim = gfc_rank_cst[n];
1790       GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
1791       if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
1792         {
1793           GFC_TYPE_ARRAY_LBOUND (type, n)
1794                 = gfc_conv_descriptor_lbound_get (desc, dim);
1795           GFC_TYPE_ARRAY_UBOUND (type, n)
1796                 = gfc_conv_descriptor_ubound_get (desc, dim);
1797         }
1798       else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
1799         {
1800           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1801                              gfc_conv_descriptor_ubound_get (desc, dim),
1802                              gfc_conv_descriptor_lbound_get (desc, dim));
1803           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1804                              GFC_TYPE_ARRAY_LBOUND (type, n),
1805                              tmp);
1806           tmp = gfc_evaluate_now (tmp, block);
1807           GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
1808         }
1809       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
1810                          GFC_TYPE_ARRAY_LBOUND (type, n),
1811                          GFC_TYPE_ARRAY_STRIDE (type, n));
1812       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
1813     }
1814   offset = gfc_evaluate_now (offset, block);
1815   GFC_TYPE_ARRAY_OFFSET (type) = offset;
1816 }
1817
1818
1819 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
1820    in SE.  The caller may still use se->expr and se->string_length after
1821    calling this function.  */
1822
1823 void
1824 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
1825                            gfc_symbol * sym, gfc_se * se,
1826                            gfc_expr *expr)
1827 {
1828   gfc_interface_sym_mapping *sm;
1829   tree desc;
1830   tree tmp;
1831   tree value;
1832   gfc_symbol *new_sym;
1833   gfc_symtree *root;
1834   gfc_symtree *new_symtree;
1835
1836   /* Create a new symbol to represent the actual argument.  */
1837   new_sym = gfc_new_symbol (sym->name, NULL);
1838   new_sym->ts = sym->ts;
1839   new_sym->as = gfc_copy_array_spec (sym->as);
1840   new_sym->attr.referenced = 1;
1841   new_sym->attr.dimension = sym->attr.dimension;
1842   new_sym->attr.pointer = sym->attr.pointer;
1843   new_sym->attr.allocatable = sym->attr.allocatable;
1844   new_sym->attr.flavor = sym->attr.flavor;
1845   new_sym->attr.function = sym->attr.function;
1846
1847   /* Ensure that the interface is available and that
1848      descriptors are passed for array actual arguments.  */
1849   if (sym->attr.flavor == FL_PROCEDURE)
1850     {
1851       new_sym->formal = expr->symtree->n.sym->formal;
1852       new_sym->attr.always_explicit
1853             = expr->symtree->n.sym->attr.always_explicit;
1854     }
1855
1856   /* Create a fake symtree for it.  */
1857   root = NULL;
1858   new_symtree = gfc_new_symtree (&root, sym->name);
1859   new_symtree->n.sym = new_sym;
1860   gcc_assert (new_symtree == root);
1861
1862   /* Create a dummy->actual mapping.  */
1863   sm = XCNEW (gfc_interface_sym_mapping);
1864   sm->next = mapping->syms;
1865   sm->old = sym;
1866   sm->new_sym = new_symtree;
1867   sm->expr = gfc_copy_expr (expr);
1868   mapping->syms = sm;
1869
1870   /* Stabilize the argument's value.  */
1871   if (!sym->attr.function && se)
1872     se->expr = gfc_evaluate_now (se->expr, &se->pre);
1873
1874   if (sym->ts.type == BT_CHARACTER)
1875     {
1876       /* Create a copy of the dummy argument's length.  */
1877       new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
1878       sm->expr->ts.u.cl = new_sym->ts.u.cl;
1879
1880       /* If the length is specified as "*", record the length that
1881          the caller is passing.  We should use the callee's length
1882          in all other cases.  */
1883       if (!new_sym->ts.u.cl->length && se)
1884         {
1885           se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
1886           new_sym->ts.u.cl->backend_decl = se->string_length;
1887         }
1888     }
1889
1890   if (!se)
1891     return;
1892
1893   /* Use the passed value as-is if the argument is a function.  */
1894   if (sym->attr.flavor == FL_PROCEDURE)
1895     value = se->expr;
1896
1897   /* If the argument is either a string or a pointer to a string,
1898      convert it to a boundless character type.  */
1899   else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
1900     {
1901       tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
1902       tmp = build_pointer_type (tmp);
1903       if (sym->attr.pointer)
1904         value = build_fold_indirect_ref_loc (input_location,
1905                                          se->expr);
1906       else
1907         value = se->expr;
1908       value = fold_convert (tmp, value);
1909     }
1910
1911   /* If the argument is a scalar, a pointer to an array or an allocatable,
1912      dereference it.  */
1913   else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
1914     value = build_fold_indirect_ref_loc (input_location,
1915                                      se->expr);
1916   
1917   /* For character(*), use the actual argument's descriptor.  */  
1918   else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
1919     value = build_fold_indirect_ref_loc (input_location,
1920                                      se->expr);
1921
1922   /* If the argument is an array descriptor, use it to determine
1923      information about the actual argument's shape.  */
1924   else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
1925            && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
1926     {
1927       /* Get the actual argument's descriptor.  */
1928       desc = build_fold_indirect_ref_loc (input_location,
1929                                       se->expr);
1930
1931       /* Create the replacement variable.  */
1932       tmp = gfc_conv_descriptor_data_get (desc);
1933       value = gfc_get_interface_mapping_array (&se->pre, sym,
1934                                                PACKED_NO, tmp);
1935
1936       /* Use DESC to work out the upper bounds, strides and offset.  */
1937       gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
1938     }
1939   else
1940     /* Otherwise we have a packed array.  */
1941     value = gfc_get_interface_mapping_array (&se->pre, sym,
1942                                              PACKED_FULL, se->expr);
1943
1944   new_sym->backend_decl = value;
1945 }
1946
1947
1948 /* Called once all dummy argument mappings have been added to MAPPING,
1949    but before the mapping is used to evaluate expressions.  Pre-evaluate
1950    the length of each argument, adding any initialization code to PRE and
1951    any finalization code to POST.  */
1952
1953 void
1954 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
1955                               stmtblock_t * pre, stmtblock_t * post)
1956 {
1957   gfc_interface_sym_mapping *sym;
1958   gfc_expr *expr;
1959   gfc_se se;
1960
1961   for (sym = mapping->syms; sym; sym = sym->next)
1962     if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
1963         && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
1964       {
1965         expr = sym->new_sym->n.sym->ts.u.cl->length;
1966         gfc_apply_interface_mapping_to_expr (mapping, expr);
1967         gfc_init_se (&se, NULL);
1968         gfc_conv_expr (&se, expr);
1969         se.expr = fold_convert (gfc_charlen_type_node, se.expr);
1970         se.expr = gfc_evaluate_now (se.expr, &se.pre);
1971         gfc_add_block_to_block (pre, &se.pre);
1972         gfc_add_block_to_block (post, &se.post);
1973
1974         sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
1975       }
1976 }
1977
1978
1979 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1980    constructor C.  */
1981
1982 static void
1983 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
1984                                      gfc_constructor * c)
1985 {
1986   for (; c; c = c->next)
1987     {
1988       gfc_apply_interface_mapping_to_expr (mapping, c->expr);
1989       if (c->iterator)
1990         {
1991           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
1992           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
1993           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
1994         }
1995     }
1996 }
1997
1998
1999 /* Like gfc_apply_interface_mapping_to_expr, but applied to
2000    reference REF.  */
2001
2002 static void
2003 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
2004                                     gfc_ref * ref)
2005 {
2006   int n;
2007
2008   for (; ref; ref = ref->next)
2009     switch (ref->type)
2010       {
2011       case REF_ARRAY:
2012         for (n = 0; n < ref->u.ar.dimen; n++)
2013           {
2014             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
2015             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
2016             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
2017           }
2018         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
2019         break;
2020
2021       case REF_COMPONENT:
2022         break;
2023
2024       case REF_SUBSTRING:
2025         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
2026         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
2027         break;
2028       }
2029 }
2030
2031
2032 /* Convert intrinsic function calls into result expressions.  */
2033
2034 static bool
2035 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
2036 {
2037   gfc_symbol *sym;
2038   gfc_expr *new_expr;
2039   gfc_expr *arg1;
2040   gfc_expr *arg2;
2041   int d, dup;
2042
2043   arg1 = expr->value.function.actual->expr;
2044   if (expr->value.function.actual->next)
2045     arg2 = expr->value.function.actual->next->expr;
2046   else
2047     arg2 = NULL;
2048
2049   sym = arg1->symtree->n.sym;
2050
2051   if (sym->attr.dummy)
2052     return false;
2053
2054   new_expr = NULL;
2055
2056   switch (expr->value.function.isym->id)
2057     {
2058     case GFC_ISYM_LEN:
2059       /* TODO figure out why this condition is necessary.  */
2060       if (sym->attr.function
2061           && (arg1->ts.u.cl->length == NULL
2062               || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
2063                   && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
2064         return false;
2065
2066       new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
2067       break;
2068
2069     case GFC_ISYM_SIZE:
2070       if (!sym->as)
2071         return false;
2072
2073       if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2074         {
2075           dup = mpz_get_si (arg2->value.integer);
2076           d = dup - 1;
2077         }
2078       else
2079         {
2080           dup = sym->as->rank;
2081           d = 0;
2082         }
2083
2084       for (; d < dup; d++)
2085         {
2086           gfc_expr *tmp;
2087
2088           if (!sym->as->upper[d] || !sym->as->lower[d])
2089             {
2090               gfc_free_expr (new_expr);
2091               return false;
2092             }
2093
2094           tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]), gfc_int_expr (1));
2095           tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
2096           if (new_expr)
2097             new_expr = gfc_multiply (new_expr, tmp);
2098           else
2099             new_expr = tmp;
2100         }
2101       break;
2102
2103     case GFC_ISYM_LBOUND:
2104     case GFC_ISYM_UBOUND:
2105         /* TODO These implementations of lbound and ubound do not limit if
2106            the size < 0, according to F95's 13.14.53 and 13.14.113.  */
2107
2108       if (!sym->as)
2109         return false;
2110
2111       if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2112         d = mpz_get_si (arg2->value.integer) - 1;
2113       else
2114         /* TODO: If the need arises, this could produce an array of
2115            ubound/lbounds.  */
2116         gcc_unreachable ();
2117
2118       if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
2119         {
2120           if (sym->as->lower[d])
2121             new_expr = gfc_copy_expr (sym->as->lower[d]);
2122         }
2123       else
2124         {
2125           if (sym->as->upper[d])
2126             new_expr = gfc_copy_expr (sym->as->upper[d]);
2127         }
2128       break;
2129
2130     default:
2131       break;
2132     }
2133
2134   gfc_apply_interface_mapping_to_expr (mapping, new_expr);
2135   if (!new_expr)
2136     return false;
2137
2138   gfc_replace_expr (expr, new_expr);
2139   return true;
2140 }
2141
2142
2143 static void
2144 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
2145                               gfc_interface_mapping * mapping)
2146 {
2147   gfc_formal_arglist *f;
2148   gfc_actual_arglist *actual;
2149
2150   actual = expr->value.function.actual;
2151   f = map_expr->symtree->n.sym->formal;
2152
2153   for (; f && actual; f = f->next, actual = actual->next)
2154     {
2155       if (!actual->expr)
2156         continue;
2157
2158       gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
2159     }
2160
2161   if (map_expr->symtree->n.sym->attr.dimension)
2162     {
2163       int d;
2164       gfc_array_spec *as;
2165
2166       as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
2167
2168       for (d = 0; d < as->rank; d++)
2169         {
2170           gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
2171           gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
2172         }
2173
2174       expr->value.function.esym->as = as;
2175     }
2176
2177   if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
2178     {
2179       expr->value.function.esym->ts.u.cl->length
2180         = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
2181
2182       gfc_apply_interface_mapping_to_expr (mapping,
2183                         expr->value.function.esym->ts.u.cl->length);
2184     }
2185 }
2186
2187
2188 /* EXPR is a copy of an expression that appeared in the interface
2189    associated with MAPPING.  Walk it recursively looking for references to
2190    dummy arguments that MAPPING maps to actual arguments.  Replace each such
2191    reference with a reference to the associated actual argument.  */
2192
2193 static void
2194 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
2195                                      gfc_expr * expr)
2196 {
2197   gfc_interface_sym_mapping *sym;
2198   gfc_actual_arglist *actual;
2199
2200   if (!expr)
2201     return;
2202
2203   /* Copying an expression does not copy its length, so do that here.  */
2204   if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
2205     {
2206       expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
2207       gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
2208     }
2209
2210   /* Apply the mapping to any references.  */
2211   gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
2212
2213   /* ...and to the expression's symbol, if it has one.  */
2214   /* TODO Find out why the condition on expr->symtree had to be moved into
2215      the loop rather than being outside it, as originally.  */
2216   for (sym = mapping->syms; sym; sym = sym->next)
2217     if (expr->symtree && sym->old == expr->symtree->n.sym)
2218       {
2219         if (sym->new_sym->n.sym->backend_decl)
2220           expr->symtree = sym->new_sym;
2221         else if (sym->expr)
2222           gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
2223       }
2224
2225       /* ...and to subexpressions in expr->value.  */
2226   switch (expr->expr_type)
2227     {
2228     case EXPR_VARIABLE:
2229     case EXPR_CONSTANT:
2230     case EXPR_NULL:
2231     case EXPR_SUBSTRING:
2232       break;
2233
2234     case EXPR_OP:
2235       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
2236       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
2237       break;
2238
2239     case EXPR_FUNCTION:
2240       for (actual = expr->value.function.actual; actual; actual = actual->next)
2241         gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
2242
2243       if (expr->value.function.esym == NULL
2244             && expr->value.function.isym != NULL
2245             && expr->value.function.actual->expr->symtree
2246             && gfc_map_intrinsic_function (expr, mapping))
2247         break;
2248
2249       for (sym = mapping->syms; sym; sym = sym->next)
2250         if (sym->old == expr->value.function.esym)
2251           {
2252             expr->value.function.esym = sym->new_sym->n.sym;
2253             gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
2254             expr->value.function.esym->result = sym->new_sym->n.sym;
2255           }
2256       break;
2257
2258     case EXPR_ARRAY:
2259     case EXPR_STRUCTURE:
2260       gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
2261       break;
2262
2263     case EXPR_COMPCALL:
2264     case EXPR_PPC:
2265       gcc_unreachable ();
2266       break;
2267     }
2268
2269   return;
2270 }
2271
2272
2273 /* Evaluate interface expression EXPR using MAPPING.  Store the result
2274    in SE.  */
2275
2276 void
2277 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
2278                              gfc_se * se, gfc_expr * expr)
2279 {
2280   expr = gfc_copy_expr (expr);
2281   gfc_apply_interface_mapping_to_expr (mapping, expr);
2282   gfc_conv_expr (se, expr);
2283   se->expr = gfc_evaluate_now (se->expr, &se->pre);
2284   gfc_free_expr (expr);
2285 }
2286
2287
2288 /* Returns a reference to a temporary array into which a component of
2289    an actual argument derived type array is copied and then returned
2290    after the function call.  */
2291 void
2292 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr,
2293                            int g77, sym_intent intent)
2294 {
2295   gfc_se lse;
2296   gfc_se rse;
2297   gfc_ss *lss;
2298   gfc_ss *rss;
2299   gfc_loopinfo loop;
2300   gfc_loopinfo loop2;
2301   gfc_ss_info *info;
2302   tree offset;
2303   tree tmp_index;
2304   tree tmp;
2305   tree base_type;
2306   stmtblock_t body;
2307   int n;
2308
2309   gcc_assert (expr->expr_type == EXPR_VARIABLE);
2310
2311   gfc_init_se (&lse, NULL);
2312   gfc_init_se (&rse, NULL);
2313
2314   /* Walk the argument expression.  */
2315   rss = gfc_walk_expr (expr);
2316
2317   gcc_assert (rss != gfc_ss_terminator);
2318  
2319   /* Initialize the scalarizer.  */
2320   gfc_init_loopinfo (&loop);
2321   gfc_add_ss_to_loop (&loop, rss);
2322
2323   /* Calculate the bounds of the scalarization.  */
2324   gfc_conv_ss_startstride (&loop);
2325
2326   /* Build an ss for the temporary.  */
2327   if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
2328     gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
2329
2330   base_type = gfc_typenode_for_spec (&expr->ts);
2331   if (GFC_ARRAY_TYPE_P (base_type)
2332                 || GFC_DESCRIPTOR_TYPE_P (base_type))
2333     base_type = gfc_get_element_type (base_type);
2334
2335   loop.temp_ss = gfc_get_ss ();;
2336   loop.temp_ss->type = GFC_SS_TEMP;
2337   loop.temp_ss->data.temp.type = base_type;
2338
2339   if (expr->ts.type == BT_CHARACTER)
2340     loop.temp_ss->string_length = expr->ts.u.cl->backend_decl;
2341   else
2342     loop.temp_ss->string_length = NULL;
2343
2344   parmse->string_length = loop.temp_ss->string_length;
2345   loop.temp_ss->data.temp.dimen = loop.dimen;
2346   loop.temp_ss->next = gfc_ss_terminator;
2347
2348   /* Associate the SS with the loop.  */
2349   gfc_add_ss_to_loop (&loop, loop.temp_ss);
2350
2351   /* Setup the scalarizing loops.  */
2352   gfc_conv_loop_setup (&loop, &expr->where);
2353
2354   /* Pass the temporary descriptor back to the caller.  */
2355   info = &loop.temp_ss->data.info;
2356   parmse->expr = info->descriptor;
2357
2358   /* Setup the gfc_se structures.  */
2359   gfc_copy_loopinfo_to_se (&lse, &loop);
2360   gfc_copy_loopinfo_to_se (&rse, &loop);
2361
2362   rse.ss = rss;
2363   lse.ss = loop.temp_ss;
2364   gfc_mark_ss_chain_used (rss, 1);
2365   gfc_mark_ss_chain_used (loop.temp_ss, 1);
2366
2367   /* Start the scalarized loop body.  */
2368   gfc_start_scalarized_body (&loop, &body);
2369
2370   /* Translate the expression.  */
2371   gfc_conv_expr (&rse, expr);
2372
2373   gfc_conv_tmp_array_ref (&lse);
2374   gfc_advance_se_ss_chain (&lse);
2375
2376   if (intent != INTENT_OUT)
2377     {
2378       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false);
2379       gfc_add_expr_to_block (&body, tmp);
2380       gcc_assert (rse.ss == gfc_ss_terminator);
2381       gfc_trans_scalarizing_loops (&loop, &body);
2382     }
2383   else
2384     {
2385       /* Make sure that the temporary declaration survives by merging
2386        all the loop declarations into the current context.  */
2387       for (n = 0; n < loop.dimen; n++)
2388         {
2389           gfc_merge_block_scope (&body);
2390           body = loop.code[loop.order[n]];
2391         }
2392       gfc_merge_block_scope (&body);
2393     }
2394
2395   /* Add the post block after the second loop, so that any
2396      freeing of allocated memory is done at the right time.  */
2397   gfc_add_block_to_block (&parmse->pre, &loop.pre);
2398
2399   /**********Copy the temporary back again.*********/
2400
2401   gfc_init_se (&lse, NULL);
2402   gfc_init_se (&rse, NULL);
2403
2404   /* Walk the argument expression.  */
2405   lss = gfc_walk_expr (expr);
2406   rse.ss = loop.temp_ss;
2407   lse.ss = lss;
2408
2409   /* Initialize the scalarizer.  */
2410   gfc_init_loopinfo (&loop2);
2411   gfc_add_ss_to_loop (&loop2, lss);
2412
2413   /* Calculate the bounds of the scalarization.  */
2414   gfc_conv_ss_startstride (&loop2);
2415
2416   /* Setup the scalarizing loops.  */
2417   gfc_conv_loop_setup (&loop2, &expr->where);
2418
2419   gfc_copy_loopinfo_to_se (&lse, &loop2);
2420   gfc_copy_loopinfo_to_se (&rse, &loop2);
2421
2422   gfc_mark_ss_chain_used (lss, 1);
2423   gfc_mark_ss_chain_used (loop.temp_ss, 1);
2424
2425   /* Declare the variable to hold the temporary offset and start the
2426      scalarized loop body.  */
2427   offset = gfc_create_var (gfc_array_index_type, NULL);
2428   gfc_start_scalarized_body (&loop2, &body);
2429
2430   /* Build the offsets for the temporary from the loop variables.  The
2431      temporary array has lbounds of zero and strides of one in all
2432      dimensions, so this is very simple.  The offset is only computed
2433      outside the innermost loop, so the overall transfer could be
2434      optimized further.  */
2435   info = &rse.ss->data.info;
2436
2437   tmp_index = gfc_index_zero_node;
2438   for (n = info->dimen - 1; n > 0; n--)
2439     {
2440       tree tmp_str;
2441       tmp = rse.loop->loopvar[n];
2442       tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2443                          tmp, rse.loop->from[n]);
2444       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2445                          tmp, tmp_index);
2446
2447       tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2448                              rse.loop->to[n-1], rse.loop->from[n-1]);
2449       tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2450                              tmp_str, gfc_index_one_node);
2451
2452       tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
2453                                tmp, tmp_str);
2454     }
2455
2456   tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2457                            tmp_index, rse.loop->from[0]);
2458   gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
2459
2460   tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2461                            rse.loop->loopvar[0], offset);
2462
2463   /* Now use the offset for the reference.  */
2464   tmp = build_fold_indirect_ref_loc (input_location,
2465                                  info->data);
2466   rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
2467
2468   if (expr->ts.type == BT_CHARACTER)
2469     rse.string_length = expr->ts.u.cl->backend_decl;
2470
2471   gfc_conv_expr (&lse, expr);
2472
2473   gcc_assert (lse.ss == gfc_ss_terminator);
2474
2475   tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
2476   gfc_add_expr_to_block (&body, tmp);
2477   
2478   /* Generate the copying loops.  */
2479   gfc_trans_scalarizing_loops (&loop2, &body);
2480
2481   /* Wrap the whole thing up by adding the second loop to the post-block
2482      and following it by the post-block of the first loop.  In this way,
2483      if the temporary needs freeing, it is done after use!  */
2484   if (intent != INTENT_IN)
2485     {
2486       gfc_add_block_to_block (&parmse->post, &loop2.pre);
2487       gfc_add_block_to_block (&parmse->post, &loop2.post);
2488     }
2489
2490   gfc_add_block_to_block (&parmse->post, &loop.post);
2491
2492   gfc_cleanup_loop (&loop);
2493   gfc_cleanup_loop (&loop2);
2494
2495   /* Pass the string length to the argument expression.  */
2496   if (expr->ts.type == BT_CHARACTER)
2497     parmse->string_length = expr->ts.u.cl->backend_decl;
2498
2499   /* We want either the address for the data or the address of the descriptor,
2500      depending on the mode of passing array arguments.  */
2501   if (g77)
2502     parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
2503   else
2504     parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
2505
2506   return;
2507 }
2508
2509
2510 /* Generate the code for argument list functions.  */
2511
2512 static void
2513 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
2514 {
2515   /* Pass by value for g77 %VAL(arg), pass the address
2516      indirectly for %LOC, else by reference.  Thus %REF
2517      is a "do-nothing" and %LOC is the same as an F95
2518      pointer.  */
2519   if (strncmp (name, "%VAL", 4) == 0)
2520     gfc_conv_expr (se, expr);
2521   else if (strncmp (name, "%LOC", 4) == 0)
2522     {
2523       gfc_conv_expr_reference (se, expr);
2524       se->expr = gfc_build_addr_expr (NULL, se->expr);
2525     }
2526   else if (strncmp (name, "%REF", 4) == 0)
2527     gfc_conv_expr_reference (se, expr);
2528   else
2529     gfc_error ("Unknown argument list function at %L", &expr->where);
2530 }
2531
2532
2533 /* Generate code for a procedure call.  Note can return se->post != NULL.
2534    If se->direct_byref is set then se->expr contains the return parameter.
2535    Return nonzero, if the call has alternate specifiers.
2536    'expr' is only needed for procedure pointer components.  */
2537
2538 int
2539 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
2540                          gfc_actual_arglist * arg, gfc_expr * expr,
2541                          tree append_args)
2542 {
2543   gfc_interface_mapping mapping;
2544   tree arglist;
2545   tree retargs;
2546   tree tmp;
2547   tree fntype;
2548   gfc_se parmse;
2549   gfc_ss *argss;
2550   gfc_ss_info *info;
2551   int byref;
2552   int parm_kind;
2553   tree type;
2554   tree var;
2555   tree len;
2556   tree stringargs;
2557   gfc_formal_arglist *formal;
2558   int has_alternate_specifier = 0;
2559   bool need_interface_mapping;
2560   bool callee_alloc;
2561   gfc_typespec ts;
2562   gfc_charlen cl;
2563   gfc_expr *e;
2564   gfc_symbol *fsym;
2565   stmtblock_t post;
2566   enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
2567   gfc_component *comp = NULL;
2568
2569   arglist = NULL_TREE;
2570   retargs = NULL_TREE;
2571   stringargs = NULL_TREE;
2572   var = NULL_TREE;
2573   len = NULL_TREE;
2574   gfc_clear_ts (&ts);
2575
2576   if (sym->from_intmod == INTMOD_ISO_C_BINDING)
2577     {
2578       if (sym->intmod_sym_id == ISOCBINDING_LOC)
2579         {
2580           if (arg->expr->rank == 0)
2581             gfc_conv_expr_reference (se, arg->expr);
2582           else
2583             {
2584               int f;
2585               /* This is really the actual arg because no formal arglist is
2586                  created for C_LOC.      */
2587               fsym = arg->expr->symtree->n.sym;
2588
2589               /* We should want it to do g77 calling convention.  */
2590               f = (fsym != NULL)
2591                 && !(fsym->attr.pointer || fsym->attr.allocatable)
2592                 && fsym->as->type != AS_ASSUMED_SHAPE;
2593               f = f || !sym->attr.always_explicit;
2594           
2595               argss = gfc_walk_expr (arg->expr);
2596               gfc_conv_array_parameter (se, arg->expr, argss, f,
2597                                         NULL, NULL, NULL);
2598             }
2599
2600           /* TODO -- the following two lines shouldn't be necessary, but
2601             they're removed a bug is exposed later in the codepath.
2602             This is workaround was thus introduced, but will have to be
2603             removed; please see PR 35150 for details about the issue.  */
2604           se->expr = convert (pvoid_type_node, se->expr);
2605           se->expr = gfc_evaluate_now (se->expr, &se->pre);
2606
2607           return 0;
2608         }
2609       else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
2610         {
2611           arg->expr->ts.type = sym->ts.u.derived->ts.type;
2612           arg->expr->ts.f90_type = sym->ts.u.derived->ts.f90_type;
2613           arg->expr->ts.kind = sym->ts.u.derived->ts.kind;
2614           gfc_conv_expr_reference (se, arg->expr);
2615       
2616           return 0;
2617         }
2618       else if ((sym->intmod_sym_id == ISOCBINDING_F_POINTER
2619                  && arg->next->expr->rank == 0)
2620                || sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)
2621         {
2622           /* Convert c_f_pointer if fptr is a scalar
2623              and convert c_f_procpointer.  */
2624           gfc_se cptrse;
2625           gfc_se fptrse;
2626
2627           gfc_init_se (&cptrse, NULL);
2628           gfc_conv_expr (&cptrse, arg->expr);
2629           gfc_add_block_to_block (&se->pre, &cptrse.pre);
2630           gfc_add_block_to_block (&se->post, &cptrse.post);
2631
2632           gfc_init_se (&fptrse, NULL);
2633           if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
2634               || gfc_is_proc_ptr_comp (arg->next->expr, NULL))
2635             fptrse.want_pointer = 1;
2636
2637           gfc_conv_expr (&fptrse, arg->next->expr);
2638           gfc_add_block_to_block (&se->pre, &fptrse.pre);
2639           gfc_add_block_to_block (&se->post, &fptrse.post);
2640
2641           if (gfc_is_proc_ptr_comp (arg->next->expr, NULL))
2642             tmp = gfc_get_ppc_type (arg->next->expr->ref->u.c.component);
2643           else
2644             tmp = TREE_TYPE (arg->next->expr->symtree->n.sym->backend_decl);
2645           se->expr = fold_build2 (MODIFY_EXPR, tmp, fptrse.expr,
2646                                   fold_convert (tmp, cptrse.expr));
2647
2648           return 0;
2649         }
2650       else if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
2651         {
2652           gfc_se arg1se;
2653           gfc_se arg2se;
2654
2655           /* Build the addr_expr for the first argument.  The argument is
2656              already an *address* so we don't need to set want_pointer in
2657              the gfc_se.  */
2658           gfc_init_se (&arg1se, NULL);
2659           gfc_conv_expr (&arg1se, arg->expr);
2660           gfc_add_block_to_block (&se->pre, &arg1se.pre);
2661           gfc_add_block_to_block (&se->post, &arg1se.post);
2662
2663           /* See if we were given two arguments.  */
2664           if (arg->next == NULL)
2665             /* Only given one arg so generate a null and do a
2666                not-equal comparison against the first arg.  */
2667             se->expr = fold_build2 (NE_EXPR, boolean_type_node, arg1se.expr,
2668                                     fold_convert (TREE_TYPE (arg1se.expr),
2669                                                   null_pointer_node));
2670           else
2671             {
2672               tree eq_expr;
2673               tree not_null_expr;
2674               
2675               /* Given two arguments so build the arg2se from second arg.  */
2676               gfc_init_se (&arg2se, NULL);
2677               gfc_conv_expr (&arg2se, arg->next->expr);
2678               gfc_add_block_to_block (&se->pre, &arg2se.pre);
2679               gfc_add_block_to_block (&se->post, &arg2se.post);
2680
2681               /* Generate test to compare that the two args are equal.  */
2682               eq_expr = fold_build2 (EQ_EXPR, boolean_type_node,
2683                                      arg1se.expr, arg2se.expr);
2684               /* Generate test to ensure that the first arg is not null.  */
2685               not_null_expr = fold_build2 (NE_EXPR, boolean_type_node,
2686                                            arg1se.expr, null_pointer_node);
2687
2688               /* Finally, the generated test must check that both arg1 is not
2689                  NULL and that it is equal to the second arg.  */
2690               se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2691                                       not_null_expr, eq_expr);
2692             }
2693
2694           return 0;
2695         }
2696     }
2697
2698   gfc_is_proc_ptr_comp (expr, &comp);
2699
2700   if (se->ss != NULL)
2701     {
2702       if (!sym->attr.elemental)
2703         {
2704           gcc_assert (se->ss->type == GFC_SS_FUNCTION);
2705           if (se->ss->useflags)
2706             {
2707               gcc_assert ((!comp && gfc_return_by_reference (sym)
2708                            && sym->result->attr.dimension)
2709                           || (comp && comp->attr.dimension));
2710               gcc_assert (se->loop != NULL);
2711
2712               /* Access the previously obtained result.  */
2713               gfc_conv_tmp_array_ref (se);
2714               gfc_advance_se_ss_chain (se);
2715               return 0;
2716             }
2717         }
2718       info = &se->ss->data.info;
2719     }
2720   else
2721     info = NULL;
2722
2723   gfc_init_block (&post);
2724   gfc_init_interface_mapping (&mapping);
2725   if (!comp)
2726     {
2727       formal = sym->formal;
2728       need_interface_mapping = sym->attr.dimension ||
2729                                (sym->ts.type == BT_CHARACTER
2730                                 && sym->ts.u.cl->length
2731                                 && sym->ts.u.cl->length->expr_type
2732                                    != EXPR_CONSTANT);
2733     }
2734   else
2735     {
2736       formal = comp->formal;
2737       need_interface_mapping = comp->attr.dimension ||
2738                                (comp->ts.type == BT_CHARACTER
2739                                 && comp->ts.u.cl->length
2740                                 && comp->ts.u.cl->length->expr_type
2741                                    != EXPR_CONSTANT);
2742     }
2743
2744   /* Evaluate the arguments.  */
2745   for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
2746     {
2747       e = arg->expr;
2748       fsym = formal ? formal->sym : NULL;
2749       parm_kind = MISSING;
2750       if (e == NULL)
2751         {
2752
2753           if (se->ignore_optional)
2754             {
2755               /* Some intrinsics have already been resolved to the correct
2756                  parameters.  */
2757               continue;
2758             }
2759           else if (arg->label)
2760             {
2761               has_alternate_specifier = 1;
2762               continue;
2763             }
2764           else
2765             {
2766               /* Pass a NULL pointer for an absent arg.  */
2767               gfc_init_se (&parmse, NULL);
2768               parmse.expr = null_pointer_node;
2769               if (arg->missing_arg_type == BT_CHARACTER)
2770                 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
2771             }
2772         }
2773       else if (fsym && fsym->ts.type == BT_CLASS
2774                  && e->ts.type == BT_DERIVED)
2775         {
2776           tree data;
2777           tree vindex;
2778
2779           /* The derived type needs to be converted to a temporary
2780              CLASS object.  */
2781           gfc_init_se (&parmse, se);
2782           type = gfc_typenode_for_spec (&fsym->ts);
2783           var = gfc_create_var (type, "class");
2784
2785           /* Get the components.  */
2786           tmp = fsym->ts.u.derived->components->backend_decl;
2787           data = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
2788                               var, tmp, NULL_TREE);
2789           tmp = fsym->ts.u.derived->components->next->backend_decl;
2790           vindex = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
2791                               var, tmp, NULL_TREE);
2792
2793           /* Set the vindex.  */
2794           tmp = build_int_cst (TREE_TYPE (vindex),
2795                                e->ts.u.derived->vindex);
2796           gfc_add_modify (&parmse.pre, vindex, tmp);
2797
2798           /* Now set the data field.  */
2799           argss = gfc_walk_expr (e);
2800           if (argss == gfc_ss_terminator)
2801             {
2802               gfc_conv_expr_reference (&parmse, e);
2803               tmp = fold_convert (TREE_TYPE (data),
2804                                   parmse.expr);
2805               gfc_add_modify (&parmse.pre, data, tmp);
2806             }
2807           else
2808             {
2809               gfc_conv_expr (&parmse, e);
2810               gfc_add_modify (&parmse.pre, data, parmse.expr);
2811             }
2812
2813           /* Pass the address of the class object.  */
2814           parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
2815         }
2816       else if (se->ss && se->ss->useflags)
2817         {
2818           /* An elemental function inside a scalarized loop.  */
2819           gfc_init_se (&parmse, se);
2820           gfc_conv_expr_reference (&parmse, e);
2821           parm_kind = ELEMENTAL;
2822         }
2823       else
2824         {
2825           /* A scalar or transformational function.  */
2826           gfc_init_se (&parmse, NULL);
2827           argss = gfc_walk_expr (e);
2828
2829           if (argss == gfc_ss_terminator)
2830             {
2831               if (e->expr_type == EXPR_VARIABLE
2832                     && e->symtree->n.sym->attr.cray_pointee
2833                     && fsym && fsym->attr.flavor == FL_PROCEDURE)
2834                 {
2835                     /* The Cray pointer needs to be converted to a pointer to
2836                        a type given by the expression.  */
2837                     gfc_conv_expr (&parmse, e);
2838                     type = build_pointer_type (TREE_TYPE (parmse.expr));
2839                     tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
2840                     parmse.expr = convert (type, tmp);
2841                 }
2842               else if (fsym && fsym->attr.value)
2843                 {
2844                   if (fsym->ts.type == BT_CHARACTER
2845                       && fsym->ts.is_c_interop
2846                       && fsym->ns->proc_name != NULL
2847                       && fsym->ns->proc_name->attr.is_bind_c)
2848                     {
2849                       parmse.expr = NULL;
2850                       gfc_conv_scalar_char_value (fsym, &parmse, &e);
2851                       if (parmse.expr == NULL)
2852                         gfc_conv_expr (&parmse, e);
2853                     }
2854                   else
2855                     gfc_conv_expr (&parmse, e);
2856                 }
2857               else if (arg->name && arg->name[0] == '%')
2858                 /* Argument list functions %VAL, %LOC and %REF are signalled
2859                    through arg->name.  */
2860                 conv_arglist_function (&parmse, arg->expr, arg->name);
2861               else if ((e->expr_type == EXPR_FUNCTION)
2862                           && e->symtree->n.sym->attr.pointer
2863                           && fsym && fsym->attr.target)
2864                 {
2865                   gfc_conv_expr (&parmse, e);
2866                   parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2867                 }
2868               else if (e->expr_type == EXPR_FUNCTION
2869                        && e->symtree->n.sym->result
2870                        && e->symtree->n.sym->result != e->symtree->n.sym
2871                        && e->symtree->n.sym->result->attr.proc_pointer)
2872                 {
2873                   /* Functions returning procedure pointers.  */
2874                   gfc_conv_expr (&parmse, e);
2875                   if (fsym && fsym->attr.proc_pointer)
2876                     parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2877                 }
2878               else
2879                 {
2880                   gfc_conv_expr_reference (&parmse, e);
2881                   if (fsym && e->expr_type != EXPR_NULL
2882                       && ((fsym->attr.pointer
2883                            && fsym->attr.flavor != FL_PROCEDURE)
2884                           || (fsym->attr.proc_pointer
2885                               && !(e->expr_type == EXPR_VARIABLE
2886                               && e->symtree->n.sym->attr.dummy))
2887                           || (e->expr_type == EXPR_VARIABLE
2888                               && gfc_is_proc_ptr_comp (e, NULL))))
2889                     {
2890                       /* Scalar pointer dummy args require an extra level of
2891                          indirection. The null pointer already contains
2892                          this level of indirection.  */
2893                       parm_kind = SCALAR_POINTER;
2894                       parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2895                     }
2896                 }
2897             }
2898           else
2899             {
2900               /* If the procedure requires an explicit interface, the actual
2901                  argument is passed according to the corresponding formal
2902                  argument.  If the corresponding formal argument is a POINTER,
2903                  ALLOCATABLE or assumed shape, we do not use g77's calling
2904                  convention, and pass the address of the array descriptor
2905                  instead. Otherwise we use g77's calling convention.  */
2906               int f;
2907               f = (fsym != NULL)
2908                   && !(fsym->attr.pointer || fsym->attr.allocatable)
2909                   && fsym->as->type != AS_ASSUMED_SHAPE;
2910               f = f || !sym->attr.always_explicit;
2911
2912               if (e->expr_type == EXPR_VARIABLE
2913                     && is_subref_array (e))
2914                 /* The actual argument is a component reference to an
2915                    array of derived types.  In this case, the argument
2916                    is converted to a temporary, which is passed and then
2917                    written back after the procedure call.  */
2918                 gfc_conv_subref_array_arg (&parmse, e, f,
2919                         fsym ? fsym->attr.intent : INTENT_INOUT);
2920               else
2921                 gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
2922                                           sym->name, NULL);
2923
2924               /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 
2925                  allocated on entry, it must be deallocated.  */
2926               if (fsym && fsym->attr.allocatable
2927                   && fsym->attr.intent == INTENT_OUT)
2928                 {
2929                   tmp = build_fold_indirect_ref_loc (input_location,
2930                                                  parmse.expr);
2931                   tmp = gfc_trans_dealloc_allocated (tmp);
2932                   gfc_add_expr_to_block (&se->pre, tmp);
2933                 }
2934
2935             } 
2936         }
2937
2938       /* The case with fsym->attr.optional is that of a user subroutine
2939          with an interface indicating an optional argument.  When we call
2940          an intrinsic subroutine, however, fsym is NULL, but we might still
2941          have an optional argument, so we proceed to the substitution
2942          just in case.  */
2943       if (e && (fsym == NULL || fsym->attr.optional))
2944         {
2945           /* If an optional argument is itself an optional dummy argument,
2946              check its presence and substitute a null if absent.  */
2947           if (e->expr_type == EXPR_VARIABLE
2948               && e->symtree->n.sym->attr.optional)
2949             gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
2950                                     e->representation.length);
2951         }
2952
2953       if (fsym && e)
2954         {
2955           /* Obtain the character length of an assumed character length
2956              length procedure from the typespec.  */
2957           if (fsym->ts.type == BT_CHARACTER
2958               && parmse.string_length == NULL_TREE
2959               && e->ts.type == BT_PROCEDURE
2960               && e->symtree->n.sym->ts.type == BT_CHARACTER
2961               && e->symtree->n.sym->ts.u.cl->length != NULL
2962               && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
2963             {
2964               gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
2965               parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
2966             }
2967         }
2968
2969       if (fsym && need_interface_mapping && e)
2970         gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
2971
2972       gfc_add_block_to_block (&se->pre, &parmse.pre);
2973       gfc_add_block_to_block (&post, &parmse.post);
2974
2975       /* Allocated allocatable components of derived types must be
2976          deallocated for non-variable scalars.  Non-variable arrays are
2977          dealt with in trans-array.c(gfc_conv_array_parameter).  */
2978       if (e && e->ts.type == BT_DERIVED
2979             && e->ts.u.derived->attr.alloc_comp
2980             && !(e->symtree && e->symtree->n.sym->attr.pointer)
2981             && (e->expr_type != EXPR_VARIABLE && !e->rank))
2982         {
2983           int parm_rank;
2984           tmp = build_fold_indirect_ref_loc (input_location,
2985                                          parmse.expr);
2986           parm_rank = e->rank;
2987           switch (parm_kind)
2988             {
2989             case (ELEMENTAL):
2990             case (SCALAR):
2991               parm_rank = 0;
2992               break;
2993
2994             case (SCALAR_POINTER):
2995               tmp = build_fold_indirect_ref_loc (input_location,
2996                                              tmp);
2997               break;
2998             }
2999
3000           if (e->expr_type == EXPR_OP
3001                 && e->value.op.op == INTRINSIC_PARENTHESES
3002                 && e->value.op.op1->expr_type == EXPR_VARIABLE)
3003             {
3004               tree local_tmp;
3005               local_tmp = gfc_evaluate_now (tmp, &se->pre);
3006               local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
3007               gfc_add_expr_to_block (&se->post, local_tmp);
3008             }
3009
3010           tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
3011
3012           gfc_add_expr_to_block (&se->post, tmp);
3013         }
3014
3015       /* Add argument checking of passing an unallocated/NULL actual to
3016          a nonallocatable/nonpointer dummy.  */
3017
3018       if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
3019         {
3020           symbol_attribute *attr;
3021           char *msg;
3022           tree cond;
3023
3024           if (e->expr_type == EXPR_VARIABLE)
3025             attr = &e->symtree->n.sym->attr;
3026           else if (e->expr_type == EXPR_FUNCTION)
3027             {
3028               /* For intrinsic functions, the gfc_attr are not available.  */
3029               if (e->symtree->n.sym->attr.generic && e->value.function.isym)
3030                 goto end_pointer_check;
3031
3032               if (e->symtree->n.sym->attr.generic)
3033                 attr = &e->value.function.esym->attr;
3034               else
3035                 attr = &e->symtree->n.sym->result->attr;
3036             }
3037           else
3038             goto end_pointer_check;
3039
3040           if (attr->optional)
3041             {
3042               /* If the actual argument is an optional pointer/allocatable and
3043                  the formal argument takes an nonpointer optional value,
3044                  it is invalid to pass a non-present argument on, even
3045                  though there is no technical reason for this in gfortran.
3046                  See Fortran 2003, Section 12.4.1.6 item (7)+(8).  */
3047               tree present, nullptr, type;
3048
3049               if (attr->allocatable
3050                   && (fsym == NULL || !fsym->attr.allocatable))
3051                 asprintf (&msg, "Allocatable actual argument '%s' is not "
3052                           "allocated or not present", e->symtree->n.sym->name);
3053               else if (attr->pointer
3054                        && (fsym == NULL || !fsym->attr.pointer))
3055                 asprintf (&msg, "Pointer actual argument '%s' is not "
3056                           "associated or not present",
3057                           e->symtree->n.sym->name);
3058               else if (attr->proc_pointer
3059                        && (fsym == NULL || !fsym->attr.proc_pointer))
3060                 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3061                           "associated or not present",
3062                           e->symtree->n.sym->name);
3063               else
3064                 goto end_pointer_check;
3065
3066               present = gfc_conv_expr_present (e->symtree->n.sym);
3067               type = TREE_TYPE (present);
3068               present = fold_build2 (EQ_EXPR, boolean_type_node, present,
3069                                      fold_convert (type, null_pointer_node));
3070               type = TREE_TYPE (parmse.expr);
3071               nullptr = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3072                                      fold_convert (type, null_pointer_node));
3073               cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node,
3074                                   present, nullptr);
3075             }
3076           else
3077             {
3078               if (attr->allocatable
3079                   && (fsym == NULL || !fsym->attr.allocatable))
3080                 asprintf (&msg, "Allocatable actual argument '%s' is not "
3081                       "allocated", e->symtree->n.sym->name);
3082               else if (attr->pointer
3083                        && (fsym == NULL || !fsym->attr.pointer))
3084                 asprintf (&msg, "Pointer actual argument '%s' is not "
3085                       "associated", e->symtree->n.sym->name);
3086               else if (attr->proc_pointer
3087                        && (fsym == NULL || !fsym->attr.proc_pointer))
3088                 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3089                       "associated", e->symtree->n.sym->name);
3090               else
3091                 goto end_pointer_check;
3092
3093
3094               cond = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3095                                   fold_convert (TREE_TYPE (parmse.expr),
3096                                                 null_pointer_node));
3097             }
3098  
3099           gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
3100                                    msg);
3101           gfc_free (msg);
3102         }
3103       end_pointer_check:
3104
3105
3106       /* Character strings are passed as two parameters, a length and a
3107          pointer - except for Bind(c) which only passes the pointer.  */
3108       if (parmse.string_length != NULL_TREE && !sym->attr.is_bind_c)
3109         stringargs = gfc_chainon_list (stringargs, parmse.string_length);
3110
3111       arglist = gfc_chainon_list (arglist, parmse.expr);
3112     }
3113   gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
3114
3115   if (comp)
3116     ts = comp->ts;
3117   else
3118    ts = sym->ts;
3119
3120   if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
3121     se->string_length = build_int_cst (gfc_charlen_type_node, 1);
3122   else if (ts.type == BT_CHARACTER)
3123     {
3124       if (ts.u.cl->length == NULL)
3125         {
3126           /* Assumed character length results are not allowed by 5.1.1.5 of the
3127              standard and are trapped in resolve.c; except in the case of SPREAD
3128              (and other intrinsics?) and dummy functions.  In the case of SPREAD,
3129              we take the character length of the first argument for the result.
3130              For dummies, we have to look through the formal argument list for
3131              this function and use the character length found there.*/
3132           if (!sym->attr.dummy)
3133             cl.backend_decl = TREE_VALUE (stringargs);
3134           else
3135             {
3136               formal = sym->ns->proc_name->formal;
3137               for (; formal; formal = formal->next)
3138                 if (strcmp (formal->sym->name, sym->name) == 0)
3139                   cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
3140             }
3141         }
3142         else
3143         {
3144           tree tmp;
3145
3146           /* Calculate the length of the returned string.  */
3147           gfc_init_se (&parmse, NULL);
3148           if (need_interface_mapping)
3149             gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
3150           else
3151             gfc_conv_expr (&parmse, ts.u.cl->length);
3152           gfc_add_block_to_block (&se->pre, &parmse.pre);
3153           gfc_add_block_to_block (&se->post, &parmse.post);
3154           
3155           tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
3156           tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
3157                              build_int_cst (gfc_charlen_type_node, 0));
3158           cl.backend_decl = tmp;
3159         }
3160
3161       /* Set up a charlen structure for it.  */
3162       cl.next = NULL;
3163       cl.length = NULL;
3164       ts.u.cl = &cl;
3165
3166       len = cl.backend_decl;
3167     }
3168
3169   byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
3170           || (!comp && gfc_return_by_reference (sym));
3171   if (byref)
3172     {
3173       if (se->direct_byref)
3174         {
3175           /* Sometimes, too much indirection can be applied; e.g. for
3176              function_result = array_valued_recursive_function.  */
3177           if (TREE_TYPE (TREE_TYPE (se->expr))
3178                 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
3179                 && GFC_DESCRIPTOR_TYPE_P
3180                         (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
3181             se->expr = build_fold_indirect_ref_loc (input_location,
3182                                                 se->expr);
3183
3184           retargs = gfc_chainon_list (retargs, se->expr);
3185         }
3186       else if (comp && comp->attr.dimension)
3187         {
3188           gcc_assert (se->loop && info);
3189
3190           /* Set the type of the array.  */
3191           tmp = gfc_typenode_for_spec (&comp->ts);
3192           info->dimen = se->loop->dimen;
3193
3194           /* Evaluate the bounds of the result, if known.  */
3195           gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
3196
3197           /* Create a temporary to store the result.  In case the function
3198              returns a pointer, the temporary will be a shallow copy and
3199              mustn't be deallocated.  */
3200           callee_alloc = comp->attr.allocatable || comp->attr.pointer;
3201           gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
3202                                        NULL_TREE, false, !comp->attr.pointer,
3203                                        callee_alloc, &se->ss->expr->where);
3204
3205           /* Pass the temporary as the first argument.  */
3206           tmp = info->descriptor;
3207           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3208           retargs = gfc_chainon_list (retargs, tmp);
3209         }
3210       else if (!comp && sym->result->attr.dimension)
3211         {
3212           gcc_assert (se->loop && info);
3213
3214           /* Set the type of the array.  */
3215           tmp = gfc_typenode_for_spec (&ts);
3216           info->dimen = se->loop->dimen;
3217
3218           /* Evaluate the bounds of the result, if known.  */
3219           gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
3220
3221           /* Create a temporary to store the result.  In case the function
3222              returns a pointer, the temporary will be a shallow copy and
3223              mustn't be deallocated.  */
3224           callee_alloc = sym->attr.allocatable || sym->attr.pointer;
3225           gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
3226                                        NULL_TREE, false, !sym->attr.pointer,
3227                                        callee_alloc, &se->ss->expr->where);
3228
3229           /* Pass the temporary as the first argument.  */
3230           tmp = info->descriptor;
3231           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3232           retargs = gfc_chainon_list (retargs, tmp);
3233         }
3234       else if (ts.type == BT_CHARACTER)
3235         {
3236           /* Pass the string length.  */
3237           type = gfc_get_character_type (ts.kind, ts.u.cl);
3238           type = build_pointer_type (type);
3239
3240           /* Return an address to a char[0:len-1]* temporary for
3241              character pointers.  */
3242           if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3243                || (comp && (comp->attr.pointer || comp->attr.allocatable)))
3244             {
3245               var = gfc_create_var (type, "pstr");
3246
3247               /* Provide an address expression for the function arguments.  */
3248               var = gfc_build_addr_expr (NULL_TREE, var);
3249             }
3250           else
3251             var = gfc_conv_string_tmp (se, type, len);
3252
3253           retargs = gfc_chainon_list (retargs, var);
3254         }
3255       else
3256         {
3257           gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
3258
3259           type = gfc_get_complex_type (ts.kind);
3260           var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
3261           retargs = gfc_chainon_list (retargs, var);
3262         }
3263
3264       /* Add the string length to the argument list.  */
3265       if (ts.type == BT_CHARACTER)
3266         retargs = gfc_chainon_list (retargs, len);
3267     }
3268   gfc_free_interface_mapping (&mapping);
3269
3270   /* Add the return arguments.  */
3271   arglist = chainon (retargs, arglist);
3272
3273   /* Add the hidden string length parameters to the arguments.  */
3274   arglist = chainon (arglist, stringargs);
3275
3276   /* We may want to append extra arguments here.  This is used e.g. for
3277      calls to libgfortran_matmul_??, which need extra information.  */
3278   if (append_args != NULL_TREE)
3279     arglist = chainon (arglist, append_args);
3280
3281   /* Generate the actual call.  */
3282   conv_function_val (se, sym, expr);
3283
3284   /* If there are alternate return labels, function type should be
3285      integer.  Can't modify the type in place though, since it can be shared
3286      with other functions.  For dummy arguments, the typing is done to
3287      to this result, even if it has to be repeated for each call.  */
3288   if (has_alternate_specifier
3289       && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
3290     {
3291       if (!sym->attr.dummy)
3292         {
3293           TREE_TYPE (sym->backend_decl)
3294                 = build_function_type (integer_type_node,
3295                       TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
3296           se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
3297         }
3298       else
3299         TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
3300     }
3301
3302   fntype = TREE_TYPE (TREE_TYPE (se->expr));
3303   se->expr = build_call_list (TREE_TYPE (fntype), se->expr, arglist);
3304
3305   /* If we have a pointer function, but we don't want a pointer, e.g.
3306      something like
3307         x = f()
3308      where f is pointer valued, we have to dereference the result.  */
3309   if (!se->want_pointer && !byref && sym->attr.pointer
3310       && !gfc_is_proc_ptr_comp (expr, NULL))
3311     se->expr = build_fold_indirect_ref_loc (input_location,
3312                                         se->expr);
3313
3314   /* f2c calling conventions require a scalar default real function to
3315      return a double precision result.  Convert this back to default
3316      real.  We only care about the cases that can happen in Fortran 77.
3317   */
3318   if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
3319       && sym->ts.kind == gfc_default_real_kind
3320       && !sym->attr.always_explicit)
3321     se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
3322
3323   /* A pure function may still have side-effects - it may modify its
3324      parameters.  */
3325   TREE_SIDE_EFFECTS (se->expr) = 1;
3326 #if 0
3327   if (!sym->attr.pure)
3328     TREE_SIDE_EFFECTS (se->expr) = 1;
3329 #endif
3330
3331   if (byref)
3332     {
3333       /* Add the function call to the pre chain.  There is no expression.  */
3334       gfc_add_expr_to_block (&se->pre, se->expr);
3335       se->expr = NULL_TREE;
3336
3337       if (!se->direct_byref)
3338         {
3339           if (sym->attr.dimension || (comp && comp->attr.dimension))
3340             {
3341               if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3342                 {
3343                   /* Check the data pointer hasn't been modified.  This would
3344                      happen in a function returning a pointer.  */
3345                   tmp = gfc_conv_descriptor_data_get (info->descriptor);
3346                   tmp = fold_build2 (NE_EXPR, boolean_type_node,
3347                                      tmp, info->data);
3348                   gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
3349                                            gfc_msg_fault);
3350                 }
3351               se->expr = info->descriptor;
3352               /* Bundle in the string length.  */
3353               se->string_length = len;
3354             }
3355           else if (ts.type == BT_CHARACTER)
3356             {
3357               /* Dereference for character pointer results.  */
3358               if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3359                   || (comp && (comp->attr.pointer || comp->attr.allocatable)))
3360                 se->expr = build_fold_indirect_ref_loc (input_location, var);
3361               else
3362                 se->expr = var;
3363
3364               se->string_length = len;
3365             }
3366           else
3367             {
3368               gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
3369               se->expr = build_fold_indirect_ref_loc (input_location, var);
3370             }
3371         }
3372     }
3373
3374   /* Follow the function call with the argument post block.  */
3375   if (byref)
3376     gfc_add_block_to_block (&se->pre, &post);
3377   else
3378     gfc_add_block_to_block (&se->post, &post);
3379
3380   return has_alternate_specifier;
3381 }
3382
3383
3384 /* Fill a character string with spaces.  */
3385
3386 static tree
3387 fill_with_spaces (tree start, tree type, tree size)
3388 {
3389   stmtblock_t block, loop;
3390   tree i, el, exit_label, cond, tmp;
3391
3392   /* For a simple char type, we can call memset().  */
3393   if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
3394     return build_call_expr_loc (input_location,
3395                             built_in_decls[BUILT_IN_MEMSET], 3, start,
3396                             build_int_cst (gfc_get_int_type (gfc_c_int_kind),
3397                                            lang_hooks.to_target_charset (' ')),
3398                             size);
3399
3400   /* Otherwise, we use a loop:
3401         for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
3402           *el = (type) ' ';
3403    */
3404
3405   /* Initialize variables.  */
3406   gfc_init_block (&block);
3407   i = gfc_create_var (sizetype, "i");
3408   gfc_add_modify (&block, i, fold_convert (sizetype, size));
3409   el = gfc_create_var (build_pointer_type (type), "el");
3410   gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
3411   exit_label = gfc_build_label_decl (NULL_TREE);
3412   TREE_USED (exit_label) = 1;
3413
3414
3415   /* Loop body.  */
3416   gfc_init_block (&loop);
3417
3418   /* Exit condition.  */
3419   cond = fold_build2 (LE_EXPR, boolean_type_node, i,
3420                       fold_convert (sizetype, integer_zero_node));
3421   tmp = build1_v (GOTO_EXPR, exit_label);
3422   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3423                      build_empty_stmt (input_location));
3424   gfc_add_expr_to_block (&loop, tmp);
3425
3426   /* Assignment.  */
3427   gfc_add_modify (&loop, fold_build1 (INDIRECT_REF, type, el),
3428                        build_int_cst (type,
3429                                       lang_hooks.to_target_charset (' ')));
3430
3431   /* Increment loop variables.  */
3432   gfc_add_modify (&loop, i, fold_build2 (MINUS_EXPR, sizetype, i,
3433                                               TYPE_SIZE_UNIT (type)));
3434   gfc_add_modify (&loop, el, fold_build2 (POINTER_PLUS_EXPR,
3435                                                TREE_TYPE (el), el,
3436                                                TYPE_SIZE_UNIT (type)));
3437
3438   /* Making the loop... actually loop!  */
3439   tmp = gfc_finish_block (&loop);
3440   tmp = build1_v (LOOP_EXPR, tmp);
3441   gfc_add_expr_to_block (&block, tmp);
3442
3443   /* The exit label.  */
3444   tmp = build1_v (LABEL_EXPR, exit_label);
3445   gfc_add_expr_to_block (&block, tmp);
3446
3447
3448   return gfc_finish_block (&block);
3449 }
3450
3451
3452 /* Generate code to copy a string.  */
3453
3454 void
3455 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
3456                        int dkind, tree slength, tree src, int skind)
3457 {
3458   tree tmp, dlen, slen;
3459   tree dsc;
3460   tree ssc;
3461   tree cond;
3462   tree cond2;
3463   tree tmp2;
3464   tree tmp3;
3465   tree tmp4;
3466   tree chartype;
3467   stmtblock_t tempblock;
3468
3469   gcc_assert (dkind == skind);
3470
3471   if (slength != NULL_TREE)
3472     {
3473       slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
3474       ssc = string_to_single_character (slen, src, skind);
3475     }
3476   else
3477     {
3478       slen = build_int_cst (size_type_node, 1);
3479       ssc =  src;
3480     }
3481
3482   if (dlength != NULL_TREE)
3483     {
3484       dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
3485       dsc = string_to_single_character (slen, dest, dkind);
3486     }
3487   else
3488     {
3489       dlen = build_int_cst (size_type_node, 1);
3490       dsc =  dest;
3491     }
3492
3493   if (slength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (src)))
3494     ssc = string_to_single_character (slen, src, skind);
3495   if (dlength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (dest)))
3496     dsc = string_to_single_character (dlen, dest, dkind);
3497
3498
3499   /* Assign directly if the types are compatible.  */
3500   if (dsc != NULL_TREE && ssc != NULL_TREE
3501       && TREE_TYPE (dsc) == TREE_TYPE (ssc))
3502     {
3503       gfc_add_modify (block, dsc, ssc);
3504       return;
3505     }
3506
3507   /* Do nothing if the destination length is zero.  */
3508   cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
3509                       build_int_cst (size_type_node, 0));
3510
3511   /* The following code was previously in _gfortran_copy_string:
3512
3513        // The two strings may overlap so we use memmove.
3514        void
3515        copy_string (GFC_INTEGER_4 destlen, char * dest,
3516                     GFC_INTEGER_4 srclen, const char * src)
3517        {
3518          if (srclen >= destlen)
3519            {
3520              // This will truncate if too long.
3521              memmove (dest, src, destlen);
3522            }
3523          else
3524            {
3525              memmove (dest, src, srclen);
3526              // Pad with spaces.
3527              memset (&dest[srclen], ' ', destlen - srclen);
3528            }
3529        }
3530
3531      We're now doing it here for better optimization, but the logic
3532      is the same.  */
3533
3534   /* For non-default character kinds, we have to multiply the string
3535      length by the base type size.  */
3536   chartype = gfc_get_char_type (dkind);
3537   slen = fold_build2 (MULT_EXPR, size_type_node,
3538                       fold_convert (size_type_node, slen),
3539                       fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
3540   dlen = fold_build2 (MULT_EXPR, size_type_node,
3541                       fold_convert (size_type_node, dlen),
3542                       fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
3543
3544   if (dlength)
3545     dest = fold_convert (pvoid_type_node, dest);
3546   else
3547     dest = gfc_build_addr_expr (pvoid_type_node, dest);
3548
3549   if (slength)
3550     src = fold_convert (pvoid_type_node, src);
3551   else
3552     src = gfc_build_addr_expr (pvoid_type_node, src);
3553
3554   /* Truncate string if source is too long.  */
3555   cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
3556   tmp2 = build_call_expr_loc (input_location,
3557                           built_in_decls[BUILT_IN_MEMMOVE],
3558                           3, dest, src, dlen);
3559
3560   /* Else copy and pad with spaces.  */
3561   tmp3 = build_call_expr_loc (input_location,
3562                           built_in_decls[BUILT_IN_MEMMOVE],
3563                           3, dest, src, slen);
3564
3565   tmp4 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest,
3566                       fold_convert (sizetype, slen));
3567   tmp4 = fill_with_spaces (tmp4, chartype,
3568                            fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
3569                                         dlen, slen));
3570
3571   gfc_init_block (&tempblock);
3572   gfc_add_expr_to_block (&tempblock, tmp3);
3573   gfc_add_expr_to_block (&tempblock, tmp4);
3574   tmp3 = gfc_finish_block (&tempblock);
3575
3576   /* The whole copy_string function is there.  */
3577   tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
3578   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3579                      build_empty_stmt (input_location));
3580   gfc_add_expr_to_block (block, tmp);
3581 }
3582
3583
3584 /* Translate a statement function.
3585    The value of a statement function reference is obtained by evaluating the
3586    expression using the values of the actual arguments for the values of the
3587    corresponding dummy arguments.  */
3588
3589 static void
3590 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
3591 {
3592   gfc_symbol *sym;
3593   gfc_symbol *fsym;
3594   gfc_formal_arglist *fargs;
3595   gfc_actual_arglist *args;
3596   gfc_se lse;
3597   gfc_se rse;
3598   gfc_saved_var *saved_vars;
3599   tree *temp_vars;
3600   tree type;
3601   tree tmp;
3602   int n;
3603
3604   sym = expr->symtree->n.sym;
3605   args = expr->value.function.actual;
3606   gfc_init_se (&lse, NULL);
3607   gfc_init_se (&rse, NULL);
3608
3609   n = 0;
3610   for (fargs = sym->formal; fargs; fargs = fargs->next)
3611     n++;
3612   saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
3613   temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
3614
3615   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3616     {
3617       /* Each dummy shall be specified, explicitly or implicitly, to be
3618          scalar.  */
3619       gcc_assert (fargs->sym->attr.dimension == 0);
3620       fsym = fargs->sym;
3621
3622       /* Create a temporary to hold the value.  */
3623       type = gfc_typenode_for_spec (&fsym->ts);
3624       temp_vars[n] = gfc_create_var (type, fsym->name);
3625
3626       if (fsym->ts.type == BT_CHARACTER)
3627         {
3628           /* Copy string arguments.  */
3629           tree arglen;
3630
3631           gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
3632                       && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
3633
3634           arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3635           tmp = gfc_build_addr_expr (build_pointer_type (type),
3636                                      temp_vars[n]);
3637
3638           gfc_conv_expr (&rse, args->expr);
3639           gfc_conv_string_parameter (&rse);
3640           gfc_add_block_to_block (&se->pre, &lse.pre);
3641           gfc_add_block_to_block (&se->pre, &rse.pre);
3642
3643           gfc_trans_string_copy (&se->pre, arglen, tmp, fsym->ts.kind,
3644                                  rse.string_length, rse.expr, fsym->ts.kind);
3645           gfc_add_block_to_block (&se->pre, &lse.post);
3646           gfc_add_block_to_block (&se->pre, &rse.post);
3647         }
3648       else
3649         {
3650           /* For everything else, just evaluate the expression.  */
3651           gfc_conv_expr (&lse, args->expr);
3652
3653           gfc_add_block_to_block (&se->pre, &lse.pre);
3654           gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
3655           gfc_add_block_to_block (&se->pre, &lse.post);
3656         }
3657
3658       args = args->next;
3659     }
3660
3661   /* Use the temporary variables in place of the real ones.  */
3662   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3663     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
3664
3665   gfc_conv_expr (se, sym->value);
3666
3667   if (sym->ts.type == BT_CHARACTER)
3668     {
3669       gfc_conv_const_charlen (sym->ts.u.cl);
3670
3671       /* Force the expression to the correct length.  */
3672       if (!INTEGER_CST_P (se->string_length)
3673           || tree_int_cst_lt (se->string_length,
3674                               sym->ts.u.cl->backend_decl))
3675         {
3676           type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
3677           tmp = gfc_create_var (type, sym->name);
3678           tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
3679           gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
3680                                  sym->ts.kind, se->string_length, se->expr,
3681                                  sym->ts.kind);
3682           se->expr = tmp;
3683         }
3684       se->string_length = sym->ts.u.cl->backend_decl;
3685     }
3686
3687   /* Restore the original variables.  */
3688   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3689     gfc_restore_sym (fargs->sym, &saved_vars[n]);
3690   gfc_free (saved_vars);
3691 }
3692
3693
3694 /* Translate a function expression.  */
3695
3696 static void
3697 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
3698 {
3699   gfc_symbol *sym;
3700
3701   if (expr->value.function.isym)
3702     {
3703       gfc_conv_intrinsic_function (se, expr);
3704       return;
3705     }
3706
3707   /* We distinguish statement functions from general functions to improve
3708      runtime performance.  */
3709   if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
3710     {
3711       gfc_conv_statement_function (se, expr);
3712       return;
3713     }
3714
3715   /* expr.value.function.esym is the resolved (specific) function symbol for
3716      most functions.  However this isn't set for dummy procedures.  */
3717   sym = expr->value.function.esym;
3718   if (!sym)
3719     sym = expr->symtree->n.sym;
3720
3721   gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
3722                           NULL_TREE);
3723 }
3724
3725
3726 static void
3727 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
3728 {
3729   gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
3730   gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
3731
3732   gfc_conv_tmp_array_ref (se);
3733   gfc_advance_se_ss_chain (se);
3734 }
3735
3736
3737 /* Build a static initializer.  EXPR is the expression for the initial value.
3738    The other parameters describe the variable of the component being 
3739    initialized. EXPR may be null.  */
3740
3741 tree
3742 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
3743                       bool array, bool pointer)
3744 {
3745   gfc_se se;
3746
3747   if (!(expr || pointer))
3748     return NULL_TREE;
3749
3750   /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
3751      (these are the only two iso_c_binding derived types that can be
3752      used as initialization expressions).  If so, we need to modify
3753      the 'expr' to be that for a (void *).  */
3754   if (expr != NULL && expr->ts.type == BT_DERIVED
3755       && expr->ts.is_iso_c && expr->ts.u.derived)
3756     {
3757       gfc_symbol *derived = expr->ts.u.derived;
3758
3759       expr = gfc_int_expr (0);
3760
3761       /* The derived symbol has already been converted to a (void *).  Use
3762          its kind.  */
3763       expr->ts.f90_type = derived->ts.f90_type;
3764       expr->ts.kind = derived->ts.kind;
3765     }
3766   
3767   if (array)
3768     {
3769       /* Arrays need special handling.  */
3770       if (pointer)
3771         return gfc_build_null_descriptor (type);
3772       else
3773         return gfc_conv_array_initializer (type, expr);
3774     }
3775   else if (pointer)
3776     return fold_convert (type, null_pointer_node);
3777   else
3778     {
3779       switch (ts->type)
3780         {
3781         case BT_DERIVED:
3782         case BT_CLASS:
3783           gfc_init_se (&se, NULL);
3784           gfc_conv_structure (&se, expr, 1);
3785           return se.expr;
3786
3787         case BT_CHARACTER:
3788           return gfc_conv_string_init (ts->u.cl->backend_decl,expr);
3789
3790         default:
3791           gfc_init_se (&se, NULL);
3792           gfc_conv_constant (&se, expr);
3793           return se.expr;
3794         }
3795     }
3796 }
3797   
3798 static tree
3799 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3800 {
3801   gfc_se rse;
3802   gfc_se lse;
3803   gfc_ss *rss;
3804   gfc_ss *lss;
3805   stmtblock_t body;
3806   stmtblock_t block;
3807   gfc_loopinfo loop;
3808   int n;
3809   tree tmp;
3810
3811   gfc_start_block (&block);
3812
3813   /* Initialize the scalarizer.  */
3814   gfc_init_loopinfo (&loop);
3815
3816   gfc_init_se (&lse, NULL);
3817   gfc_init_se (&rse, NULL);
3818
3819   /* Walk the rhs.  */
3820   rss = gfc_walk_expr (expr);
3821   if (rss == gfc_ss_terminator)
3822     {
3823       /* The rhs is scalar.  Add a ss for the expression.  */
3824       rss = gfc_get_ss ();
3825       rss->next = gfc_ss_terminator;
3826       rss->type = GFC_SS_SCALAR;
3827       rss->expr = expr;
3828     }
3829
3830   /* Create a SS for the destination.  */
3831   lss = gfc_get_ss ();
3832   lss->type = GFC_SS_COMPONENT;
3833   lss->expr = NULL;
3834   lss->shape = gfc_get_shape (cm->as->rank);
3835   lss->next = gfc_ss_terminator;
3836   lss->data.info.dimen = cm->as->rank;
3837   lss->data.info.descriptor = dest;
3838   lss->data.info.data = gfc_conv_array_data (dest);
3839   lss->data.info.offset = gfc_conv_array_offset (dest);
3840   for (n = 0; n < cm->as->rank; n++)
3841     {
3842       lss->data.info.dim[n] = n;
3843       lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
3844       lss->data.info.stride[n] = gfc_index_one_node;
3845
3846       mpz_init (lss->shape[n]);
3847       mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
3848                cm->as->lower[n]->value.integer);
3849       mpz_add_ui (lss->shape[n], lss->shape[n], 1);
3850     }
3851   
3852   /* Associate the SS with the loop.  */
3853   gfc_add_ss_to_loop (&loop, lss);
3854   gfc_add_ss_to_loop (&loop, rss);
3855
3856   /* Calculate the bounds of the scalarization.  */
3857   gfc_conv_ss_startstride (&loop);
3858
3859   /* Setup the scalarizing loops.  */
3860   gfc_conv_loop_setup (&loop, &expr->where);
3861
3862   /* Setup the gfc_se structures.  */
3863   gfc_copy_loopinfo_to_se (&lse, &loop);
3864   gfc_copy_loopinfo_to_se (&rse, &loop);
3865
3866   rse.ss = rss;
3867   gfc_mark_ss_chain_used (rss, 1);
3868   lse.ss = lss;
3869   gfc_mark_ss_chain_used (lss, 1);
3870
3871   /* Start the scalarized loop body.  */
3872   gfc_start_scalarized_body (&loop, &body);
3873
3874   gfc_conv_tmp_array_ref (&lse);
3875   if (cm->ts.type == BT_CHARACTER)
3876     lse.string_length = cm->ts.u.cl->backend_decl;
3877
3878   gfc_conv_expr (&rse, expr);
3879
3880   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
3881   gfc_add_expr_to_block (&body, tmp);
3882
3883   gcc_assert (rse.ss == gfc_ss_terminator);
3884
3885   /* Generate the copying loops.  */
3886   gfc_trans_scalarizing_loops (&loop, &body);
3887
3888   /* Wrap the whole thing up.  */
3889   gfc_add_block_to_block (&block, &loop.pre);
3890   gfc_add_block_to_block (&block, &loop.post);
3891
3892   for (n = 0; n < cm->as->rank; n++)
3893     mpz_clear (lss->shape[n]);
3894   gfc_free (lss->shape);
3895
3896   gfc_cleanup_loop (&loop);
3897
3898   return gfc_finish_block (&block);
3899 }
3900
3901
3902 /* Assign a single component of a derived type constructor.  */
3903
3904 static tree
3905 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3906 {
3907   gfc_se se;
3908   gfc_se lse;
3909   gfc_ss *rss;
3910   stmtblock_t block;
3911   tree tmp;
3912   tree offset;
3913   int n;
3914
3915   gfc_start_block (&block);
3916
3917   if (cm->attr.pointer)
3918     {
3919       gfc_init_se (&se, NULL);
3920       /* Pointer component.  */
3921       if (cm->attr.dimension)
3922         {
3923           /* Array pointer.  */
3924           if (expr->expr_type == EXPR_NULL)
3925             gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
3926           else
3927             {
3928               rss = gfc_walk_expr (expr);
3929               se.direct_byref = 1;
3930               se.expr = dest;
3931               gfc_conv_expr_descriptor (&se, expr, rss);
3932               gfc_add_block_to_block (&block, &se.pre);
3933               gfc_add_block_to_block (&block, &se.post);
3934             }
3935         }
3936       else
3937         {
3938           /* Scalar pointers.  */
3939           se.want_pointer = 1;
3940           gfc_conv_expr (&se, expr);
3941           gfc_add_block_to_block (&block, &se.pre);
3942           gfc_add_modify (&block, dest,
3943                                fold_convert (TREE_TYPE (dest), se.expr));
3944           gfc_add_block_to_block (&block, &se.post);
3945         }
3946     }
3947   else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
3948     {
3949       /* NULL initialization for CLASS components.  */
3950       tmp = gfc_trans_structure_assign (dest,
3951                                         gfc_default_initializer (&cm->ts));
3952       gfc_add_expr_to_block (&block, tmp);
3953     }
3954   else if (cm->attr.dimension)
3955     {
3956       if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
3957         gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
3958       else if (cm->attr.allocatable)
3959         {
3960           tree tmp2;
3961
3962           gfc_init_se (&se, NULL);
3963  
3964           rss = gfc_walk_expr (expr);
3965           se.want_pointer = 0;
3966           gfc_conv_expr_descriptor (&se, expr, rss);
3967           gfc_add_block_to_block (&block, &se.pre);
3968           gfc_add_modify (&block, dest, se.expr);
3969
3970           if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
3971             tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr, dest,
3972                                        cm->as->rank);
3973           else
3974             tmp = gfc_duplicate_allocatable (dest, se.expr,
3975                                              TREE_TYPE(cm->backend_decl),
3976                                              cm->as->rank);
3977
3978           gfc_add_expr_to_block (&block, tmp);
3979           gfc_add_block_to_block (&block, &se.post);
3980
3981           if (expr->expr_type != EXPR_VARIABLE)
3982             gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
3983
3984           /* Shift the lbound and ubound of temporaries to being unity, rather
3985              than zero, based.  Calculate the offset for all cases.  */
3986           offset = gfc_conv_descriptor_offset_get (dest);
3987           gfc_add_modify (&block, offset, gfc_index_zero_node);
3988           tmp2 =gfc_create_var (gfc_array_index_type, NULL);
3989           for (n = 0; n < expr->rank; n++)
3990             {
3991               if (expr->expr_type != EXPR_VARIABLE
3992                     && expr->expr_type != EXPR_CONSTANT)
3993                 {
3994                   tree span;
3995                   tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
3996                   span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
3997                             gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
3998                   tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3999                                      span, gfc_index_one_node);
4000                   gfc_conv_descriptor_ubound_set (&block, dest, gfc_rank_cst[n],
4001                                                   tmp);
4002                   gfc_conv_descriptor_lbound_set (&block, dest, gfc_rank_cst[n],
4003                                                   gfc_index_one_node);
4004                 }
4005               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4006                                  gfc_conv_descriptor_lbound_get (dest,
4007                                                              gfc_rank_cst[n]),
4008                                  gfc_conv_descriptor_stride_get (dest,
4009                                                              gfc_rank_cst[n]));
4010               gfc_add_modify (&block, tmp2, tmp);
4011               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
4012               gfc_conv_descriptor_offset_set (&block, dest, tmp);
4013             }
4014
4015           if (expr->expr_type == EXPR_FUNCTION
4016                 && expr->value.function.isym
4017                 && expr->value.function.isym->conversion
4018                 && expr->value.function.actual->expr
4019                 && expr->value.function.actual->expr->expr_type
4020                                                 == EXPR_VARIABLE)
4021             {
4022               /* If a conversion expression has a null data pointer
4023                  argument, nullify the allocatable component.  */
4024               gfc_symbol *s;
4025               tree non_null_expr;
4026               tree null_expr;
4027               s = expr->value.function.actual->expr->symtree->n.sym;
4028               if (s->attr.allocatable || s->attr.pointer)
4029                 {
4030                   non_null_expr = gfc_finish_block (&block);
4031                   gfc_start_block (&block);
4032                   gfc_conv_descriptor_data_set (&block, dest,
4033                                                 null_pointer_node);
4034                   null_expr = gfc_finish_block (&block);
4035                   tmp = gfc_conv_descriptor_data_get (s->backend_decl);
4036                   tmp = build2 (EQ_EXPR, boolean_type_node, tmp,
4037                                 fold_convert (TREE_TYPE (tmp),
4038                                               null_pointer_node));
4039                   return build3_v (COND_EXPR, tmp, null_expr,
4040                                    non_null_expr);
4041                 }
4042             }
4043         }
4044       else
4045         {
4046           tmp = gfc_trans_subarray_assign (dest, cm, expr);
4047           gfc_add_expr_to_block (&block, tmp);
4048         }
4049     }
4050   else if (expr->ts.type == BT_DERIVED)
4051     {
4052       if (expr->expr_type != EXPR_STRUCTURE)
4053         {
4054           gfc_init_se (&se, NULL);
4055           gfc_conv_expr (&se, expr);
4056           gfc_add_block_to_block (&block, &se.pre);
4057           gfc_add_modify (&block, dest,
4058                                fold_convert (TREE_TYPE (dest), se.expr));
4059           gfc_add_block_to_block (&block, &se.post);
4060         }
4061       else
4062         {
4063           /* Nested constructors.  */
4064           tmp = gfc_trans_structure_assign (dest, expr);
4065           gfc_add_expr_to_block (&block, tmp);
4066         }
4067     }
4068   else
4069     {
4070       /* Scalar component.  */
4071       gfc_init_se (&se, NULL);
4072       gfc_init_se (&lse, NULL);
4073
4074       gfc_conv_expr (&se, expr);
4075       if (cm->ts.type == BT_CHARACTER)
4076         lse.string_length = cm->ts.u.cl->backend_decl;
4077       lse.expr = dest;
4078       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
4079       gfc_add_expr_to_block (&block, tmp);
4080     }
4081   return gfc_finish_block (&block);
4082 }
4083
4084 /* Assign a derived type constructor to a variable.  */
4085
4086 static tree
4087 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
4088 {
4089   gfc_constructor *c;
4090   gfc_component *cm;
4091   stmtblock_t block;
4092   tree field;
4093   tree tmp;
4094
4095   gfc_start_block (&block);
4096   cm = expr->ts.u.derived->components;
4097   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
4098     {
4099       /* Skip absent members in default initializers.  */
4100       if (!c->expr)
4101         continue;
4102
4103       field = cm->backend_decl;
4104       tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field),
4105                          dest, field, NULL_TREE);
4106       tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
4107       gfc_add_expr_to_block (&block, tmp);
4108     }
4109   return gfc_finish_block (&block);
4110 }
4111
4112 /* Build an expression for a constructor. If init is nonzero then
4113    this is part of a static variable initializer.  */
4114
4115 void
4116 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
4117 {
4118   gfc_constructor *c;
4119   gfc_component *cm;
4120   tree val;
4121   tree type;
4122   tree tmp;
4123   VEC(constructor_elt,gc) *v = NULL;
4124
4125   gcc_assert (se->ss == NULL);
4126   gcc_assert (expr->expr_type == EXPR_STRUCTURE);
4127   type = gfc_typenode_for_spec (&expr->ts);
4128
4129   if (!init)
4130     {
4131       /* Create a temporary variable and fill it in.  */
4132       se->expr = gfc_create_var (type, expr->ts.u.derived->name);
4133       tmp = gfc_trans_structure_assign (se->expr, expr);
4134       gfc_add_expr_to_block (&se->pre, tmp);
4135       return;
4136     }
4137
4138   cm = expr->ts.u.derived->components;
4139
4140   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
4141     {
4142       /* Skip absent members in default initializers and allocatable
4143          components.  Although the latter have a default initializer
4144          of EXPR_NULL,... by default, the static nullify is not needed
4145          since this is done every time we come into scope.  */
4146       if (!c->expr || cm->attr.allocatable)
4147         continue;
4148
4149       if (cm->ts.type == BT_CLASS)
4150         {
4151           val = gfc_conv_initializer (c->expr, &cm->ts,
4152               TREE_TYPE (cm->ts.u.derived->components->backend_decl),
4153               cm->ts.u.derived->components->attr.dimension,
4154               cm->ts.u.derived->components->attr.pointer);
4155
4156           /* Append it to the constructor list.  */
4157           CONSTRUCTOR_APPEND_ELT (v, cm->ts.u.derived->components->backend_decl,
4158                                   val);
4159         }
4160       else
4161         {
4162           val = gfc_conv_initializer (c->expr, &cm->ts,
4163               TREE_TYPE (cm->backend_decl), cm->attr.dimension,
4164               cm->attr.pointer || cm->attr.proc_pointer);
4165
4166           /* Append it to the constructor list.  */
4167           CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
4168         }
4169     }
4170   se->expr = build_constructor (type, v);
4171   if (init) 
4172     TREE_CONSTANT (se->expr) = 1;
4173 }
4174
4175
4176 /* Translate a substring expression.  */
4177
4178 static void
4179 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
4180 {
4181   gfc_ref *ref;
4182
4183   ref = expr->ref;
4184
4185   gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
4186
4187   se->expr = gfc_build_wide_string_const (expr->ts.kind,
4188                                           expr->value.character.length,
4189                                           expr->value.character.string);
4190
4191   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
4192   TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
4193
4194   if (ref)
4195     gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
4196 }
4197
4198
4199 /* Entry point for expression translation.  Evaluates a scalar quantity.
4200    EXPR is the expression to be translated, and SE is the state structure if
4201    called from within the scalarized.  */
4202
4203 void
4204 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
4205 {
4206   if (se->ss && se->ss->expr == expr
4207       && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
4208     {
4209       /* Substitute a scalar expression evaluated outside the scalarization
4210          loop.  */
4211       se->expr = se->ss->data.scalar.expr;
4212       se->string_length = se->ss->string_length;
4213       gfc_advance_se_ss_chain (se);
4214       return;
4215     }
4216
4217   /* We need to convert the expressions for the iso_c_binding derived types.
4218      C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
4219      null_pointer_node.  C_PTR and C_FUNPTR are converted to match the
4220      typespec for the C_PTR and C_FUNPTR symbols, which has already been
4221      updated to be an integer with a kind equal to the size of a (void *).  */
4222   if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
4223       && expr->ts.u.derived->attr.is_iso_c)
4224     {
4225       if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
4226           || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
4227         {
4228           /* Set expr_type to EXPR_NULL, which will result in
4229              null_pointer_node being used below.  */
4230           expr->expr_type = EXPR_NULL;
4231         }
4232       else
4233         {
4234           /* Update the type/kind of the expression to be what the new
4235              type/kind are for the updated symbols of C_PTR/C_FUNPTR.  */
4236           expr->ts.type = expr->ts.u.derived->ts.type;
4237           expr->ts.f90_type = expr->ts.u.derived->ts.f90_type;
4238           expr->ts.kind = expr->ts.u.derived->ts.kind;
4239         }
4240     }
4241   
4242   switch (expr->expr_type)
4243     {
4244     case EXPR_OP:
4245       gfc_conv_expr_op (se, expr);
4246       break;
4247
4248     case EXPR_FUNCTION:
4249       gfc_conv_function_expr (se, expr);
4250       break;
4251
4252     case EXPR_CONSTANT:
4253       gfc_conv_constant (se, expr);
4254       break;
4255
4256     case EXPR_VARIABLE:
4257       gfc_conv_variable (se, expr);
4258       break;
4259
4260     case EXPR_NULL:
4261       se->expr = null_pointer_node;
4262       break;
4263
4264     case EXPR_SUBSTRING:
4265       gfc_conv_substring_expr (se, expr);
4266       break;
4267
4268     case EXPR_STRUCTURE:
4269       gfc_conv_structure (se, expr, 0);
4270       break;
4271
4272     case EXPR_ARRAY:
4273       gfc_conv_array_constructor_expr (se, expr);
4274       break;
4275
4276     default:
4277       gcc_unreachable ();
4278       break;
4279     }
4280 }
4281
4282 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
4283    of an assignment.  */
4284 void
4285 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
4286 {
4287   gfc_conv_expr (se, expr);
4288   /* All numeric lvalues should have empty post chains.  If not we need to
4289      figure out a way of rewriting an lvalue so that it has no post chain.  */
4290   gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
4291 }
4292
4293 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
4294    numeric expressions.  Used for scalar values where inserting cleanup code
4295    is inconvenient.  */
4296 void
4297 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
4298 {
4299   tree val;
4300
4301   gcc_assert (expr->ts.type != BT_CHARACTER);
4302   gfc_conv_expr (se, expr);
4303   if (se->post.head)
4304     {
4305       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
4306       gfc_add_modify (&se->pre, val, se->expr);
4307       se->expr = val;
4308       gfc_add_block_to_block (&se->pre, &se->post);
4309     }
4310 }
4311
4312 /* Helper to translate an expression and convert it to a particular type.  */
4313 void
4314 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
4315 {
4316   gfc_conv_expr_val (se, expr);
4317   se->expr = convert (type, se->expr);
4318 }
4319
4320
4321 /* Converts an expression so that it can be passed by reference.  Scalar
4322    values only.  */
4323
4324 void
4325 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
4326 {
4327   tree var;
4328
4329   if (se->ss && se->ss->expr == expr
4330       && se->ss->type == GFC_SS_REFERENCE)
4331     {
4332       se->expr = se->ss->data.scalar.expr;
4333       se->string_length = se->ss->string_length;
4334       gfc_advance_se_ss_chain (se);
4335       return;
4336     }
4337
4338   if (expr->ts.type == BT_CHARACTER)
4339     {
4340       gfc_conv_expr (se, expr);
4341       gfc_conv_string_parameter (se);
4342       return;
4343     }
4344
4345   if (expr->expr_type == EXPR_VARIABLE)
4346     {
4347       se->want_pointer = 1;
4348       gfc_conv_expr (se, expr);
4349       if (se->post.head)
4350         {
4351           var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4352           gfc_add_modify (&se->pre, var, se->expr);
4353           gfc_add_block_to_block (&se->pre, &se->post);
4354           se->expr = var;
4355         }
4356       return;
4357     }
4358
4359   if (expr->expr_type == EXPR_FUNCTION
4360         && expr->symtree->n.sym->attr.pointer
4361         && !expr->symtree->n.sym->attr.dimension)
4362     {
4363       se->want_pointer = 1;
4364       gfc_conv_expr (se, expr);
4365       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4366       gfc_add_modify (&se->pre, var, se->expr);
4367       se->expr = var;
4368       return;
4369     }
4370
4371
4372   gfc_conv_expr (se, expr);
4373
4374   /* Create a temporary var to hold the value.  */
4375   if (TREE_CONSTANT (se->expr))
4376     {
4377       tree tmp = se->expr;
4378       STRIP_TYPE_NOPS (tmp);
4379       var = build_decl (input_location,
4380                         CONST_DECL, NULL, TREE_TYPE (tmp));
4381       DECL_INITIAL (var) = tmp;
4382       TREE_STATIC (var) = 1;
4383       pushdecl (var);
4384     }
4385   else
4386     {
4387       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4388       gfc_add_modify (&se->pre, var, se->expr);
4389     }
4390   gfc_add_block_to_block (&se->pre, &se->post);
4391
4392   /* Take the address of that value.  */
4393   se->expr = gfc_build_addr_expr (NULL_TREE, var);
4394 }
4395
4396
4397 tree
4398 gfc_trans_pointer_assign (gfc_code * code)
4399 {
4400   return gfc_trans_pointer_assignment (code->expr1, code->expr2);
4401 }
4402
4403
4404 /* Generate code for a pointer assignment.  */
4405
4406 tree
4407 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
4408 {
4409   gfc_se lse;
4410   gfc_se rse;
4411   gfc_ss *lss;
4412   gfc_ss *rss;
4413   stmtblock_t block;
4414   tree desc;
4415   tree tmp;
4416   tree decl;
4417
4418   gfc_start_block (&block);
4419
4420   gfc_init_se (&lse, NULL);
4421
4422   lss = gfc_walk_expr (expr1);
4423   rss = gfc_walk_expr (expr2);
4424   if (lss == gfc_ss_terminator)
4425     {
4426       /* Scalar pointers.  */
4427       lse.want_pointer = 1;
4428       gfc_conv_expr (&lse, expr1);
4429       gcc_assert (rss == gfc_ss_terminator);
4430       gfc_init_se (&rse, NULL);
4431       rse.want_pointer = 1;
4432       gfc_conv_expr (&rse, expr2);
4433
4434       if (expr1->symtree->n.sym->attr.proc_pointer
4435           && expr1->symtree->n.sym->attr.dummy)
4436         lse.expr = build_fold_indirect_ref_loc (input_location,
4437                                             lse.expr);
4438
4439       if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
4440           && expr2->symtree->n.sym->attr.dummy)
4441         rse.expr = build_fold_indirect_ref_loc (input_location,
4442                                             rse.expr);
4443
4444       gfc_add_block_to_block (&block, &lse.pre);
4445       gfc_add_block_to_block (&block, &rse.pre);
4446
4447       /* Check character lengths if character expression.  The test is only
4448          really added if -fbounds-check is enabled.  */
4449       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
4450           && !expr1->symtree->n.sym->attr.proc_pointer
4451           && !gfc_is_proc_ptr_comp (expr1, NULL))
4452         {
4453           gcc_assert (expr2->ts.type == BT_CHARACTER);
4454           gcc_assert (lse.string_length && rse.string_length);
4455           gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4456                                        lse.string_length, rse.string_length,
4457                                        &block);
4458         }
4459
4460       gfc_add_modify (&block, lse.expr,
4461                            fold_convert (TREE_TYPE (lse.expr), rse.expr));
4462
4463       gfc_add_block_to_block (&block, &rse.post);
4464       gfc_add_block_to_block (&block, &lse.post);
4465     }
4466   else
4467     {
4468       tree strlen_lhs;
4469       tree strlen_rhs = NULL_TREE;
4470
4471       /* Array pointer.  */
4472       gfc_conv_expr_descriptor (&lse, expr1, lss);
4473       strlen_lhs = lse.string_length;
4474       switch (expr2->expr_type)
4475         {
4476         case EXPR_NULL:
4477           /* Just set the data pointer to null.  */
4478           gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
4479           break;
4480
4481         case EXPR_VARIABLE:
4482           /* Assign directly to the pointer's descriptor.  */
4483           lse.direct_byref = 1;
4484           gfc_conv_expr_descriptor (&lse, expr2, rss);
4485           strlen_rhs = lse.string_length;
4486
4487           /* If this is a subreference array pointer assignment, use the rhs
4488              descriptor element size for the lhs span.  */
4489           if (expr1->symtree->n.sym->attr.subref_array_pointer)
4490             {
4491               decl = expr1->symtree->n.sym->backend_decl;
4492               gfc_init_se (&rse, NULL);
4493               rse.descriptor_only = 1;
4494               gfc_conv_expr (&rse, expr2);
4495               tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
4496               tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
4497               if (!INTEGER_CST_P (tmp))
4498                 gfc_add_block_to_block (&lse.post, &rse.pre);
4499               gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
4500             }
4501
4502           break;
4503
4504         default:
4505           /* Assign to a temporary descriptor and then copy that
4506              temporary to the pointer.  */
4507           desc = lse.expr;
4508           tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
4509
4510           lse.expr = tmp;
4511           lse.direct_byref = 1;
4512           gfc_conv_expr_descriptor (&lse, expr2, rss);
4513           strlen_rhs = lse.string_length;
4514           gfc_add_modify (&lse.pre, desc, tmp);
4515           break;
4516         }
4517
4518       gfc_add_block_to_block (&block, &lse.pre);
4519
4520       /* Check string lengths if applicable.  The check is only really added
4521          to the output code if -fbounds-check is enabled.  */
4522       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
4523         {
4524           gcc_assert (expr2->ts.type == BT_CHARACTER);
4525           gcc_assert (strlen_lhs && strlen_rhs);
4526           gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4527                                        strlen_lhs, strlen_rhs, &block);
4528         }
4529
4530       gfc_add_block_to_block (&block, &lse.post);
4531     }
4532   return gfc_finish_block (&block);
4533 }
4534
4535
4536 /* Makes sure se is suitable for passing as a function string parameter.  */
4537 /* TODO: Need to check all callers of this function.  It may be abused.  */
4538
4539 void
4540 gfc_conv_string_parameter (gfc_se * se)
4541 {
4542   tree type;
4543
4544   if (TREE_CODE (se->expr) == STRING_CST)
4545     {
4546       type = TREE_TYPE (TREE_TYPE (se->expr));
4547       se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4548       return;
4549     }
4550
4551   if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
4552     {
4553       if (TREE_CODE (se->expr) != INDIRECT_REF)
4554         {
4555           type = TREE_TYPE (se->expr);
4556           se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4557         }
4558       else
4559         {
4560           type = gfc_get_character_type_len (gfc_default_character_kind,
4561                                              se->string_length);
4562           type = build_pointer_type (type);
4563           se->expr = gfc_build_addr_expr (type, se->expr);
4564         }
4565     }
4566
4567   gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
4568   gcc_assert (se->string_length
4569           && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
4570 }
4571
4572
4573 /* Generate code for assignment of scalar variables.  Includes character
4574    strings and derived types with allocatable components.  */
4575
4576 tree
4577 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
4578                          bool l_is_temp, bool r_is_var)
4579 {
4580   stmtblock_t block;
4581   tree tmp;
4582   tree cond;
4583
4584   gfc_init_block (&block);
4585
4586   if (ts.type == BT_CHARACTER)
4587     {
4588       tree rlen = NULL;
4589       tree llen = NULL;
4590
4591       if (lse->string_length != NULL_TREE)
4592         {
4593           gfc_conv_string_parameter (lse);
4594           gfc_add_block_to_block (&block, &lse->pre);
4595           llen = lse->string_length;
4596         }
4597
4598       if (rse->string_length != NULL_TREE)
4599         {
4600           gcc_assert (rse->string_length != NULL_TREE);
4601           gfc_conv_string_parameter (rse);
4602           gfc_add_block_to_block (&block, &rse->pre);
4603           rlen = rse->string_length;
4604         }
4605
4606       gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
4607                              rse->expr, ts.kind);
4608     }
4609   else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
4610     {
4611       cond = NULL_TREE;
4612         
4613       /* Are the rhs and the lhs the same?  */
4614       if (r_is_var)
4615         {
4616           cond = fold_build2 (EQ_EXPR, boolean_type_node,
4617                               gfc_build_addr_expr (NULL_TREE, lse->expr),
4618                               gfc_build_addr_expr (NULL_TREE, rse->expr));
4619           cond = gfc_evaluate_now (cond, &lse->pre);
4620         }
4621
4622       /* Deallocate the lhs allocated components as long as it is not
4623          the same as the rhs.  This must be done following the assignment
4624          to prevent deallocating data that could be used in the rhs
4625          expression.  */
4626       if (!l_is_temp)
4627         {
4628           tmp = gfc_evaluate_now (lse->expr, &lse->pre);
4629           tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
4630           if (r_is_var)
4631             tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4632                             tmp);
4633           gfc_add_expr_to_block (&lse->post, tmp);
4634         }
4635
4636       gfc_add_block_to_block (&block, &rse->pre);
4637       gfc_add_block_to_block (&block, &lse->pre);
4638
4639       gfc_add_modify (&block, lse->expr,
4640                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
4641
4642       /* Do a deep copy if the rhs is a variable, if it is not the
4643          same as the lhs.  */
4644       if (r_is_var)
4645         {
4646           tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
4647           tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4648                           tmp);
4649           gfc_add_expr_to_block (&block, tmp);
4650         }
4651     }
4652   else if (ts.type == BT_DERIVED)
4653     {
4654       gfc_add_block_to_block (&block, &lse->pre);
4655       gfc_add_block_to_block (&block, &rse->pre);
4656       tmp = gfc_evaluate_now (rse->expr, &block);
4657       tmp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lse->expr), tmp);
4658       gfc_add_modify (&block, lse->expr, tmp);
4659     }
4660   else
4661     {
4662       gfc_add_block_to_block (&block, &lse->pre);
4663       gfc_add_block_to_block (&block, &rse->pre);
4664
4665       gfc_add_modify (&block, lse->expr,
4666                       fold_convert (TREE_TYPE (lse->expr), rse->expr));
4667     }
4668
4669   gfc_add_block_to_block (&block, &lse->post);
4670   gfc_add_block_to_block (&block, &rse->post);
4671
4672   return gfc_finish_block (&block);
4673 }
4674
4675
4676 /* Try to translate array(:) = func (...), where func is a transformational
4677    array function, without using a temporary.  Returns NULL is this isn't the
4678    case.  */
4679
4680 static tree
4681 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
4682 {
4683   gfc_se se;
4684   gfc_ss *ss;
4685   gfc_ref * ref;
4686   bool seen_array_ref;
4687   bool c = false;
4688   gfc_component *comp = NULL;
4689
4690   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
4691   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
4692     return NULL;
4693
4694   /* Elemental functions don't need a temporary anyway.  */
4695   if (expr2->value.function.esym != NULL
4696       && expr2->value.function.esym->attr.elemental)
4697     return NULL;
4698
4699   /* Fail if rhs is not FULL or a contiguous section.  */
4700   if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
4701     return NULL;
4702
4703   /* Fail if EXPR1 can't be expressed as a descriptor.  */
4704   if (gfc_ref_needs_temporary_p (expr1->ref))
4705     return NULL;
4706
4707   /* Functions returning pointers need temporaries.  */
4708   if (expr2->symtree->n.sym->attr.pointer 
4709       || expr2->symtree->n.sym->attr.allocatable)
4710     return NULL;
4711
4712   /* Character array functions need temporaries unless the
4713      character lengths are the same.  */
4714   if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
4715     {
4716       if (expr1->ts.u.cl->length == NULL
4717             || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
4718         return NULL;
4719
4720       if (expr2->ts.u.cl->length == NULL
4721             || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
4722         return NULL;
4723
4724       if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
4725                      expr2->ts.u.cl->length->value.integer) != 0)
4726         return NULL;
4727     }
4728
4729   /* Check that no LHS component references appear during an array
4730      reference. This is needed because we do not have the means to
4731      span any arbitrary stride with an array descriptor. This check
4732      is not needed for the rhs because the function result has to be
4733      a complete type.  */
4734   seen_array_ref = false;
4735   for (ref = expr1->ref; ref; ref = ref->next)
4736     {
4737       if (ref->type == REF_ARRAY)
4738         seen_array_ref= true;
4739       else if (ref->type == REF_COMPONENT && seen_array_ref)
4740         return NULL;
4741     }
4742
4743   /* Check for a dependency.  */
4744   if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
4745                                    expr2->value.function.esym,
4746                                    expr2->value.function.actual,
4747                                    NOT_ELEMENTAL))
4748     return NULL;
4749
4750   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
4751      functions.  */
4752   gcc_assert (expr2->value.function.isym
4753               || (gfc_is_proc_ptr_comp (expr2, &comp)
4754                   && comp && comp->attr.dimension)
4755               || (!comp && gfc_return_by_reference (expr2->value.function.esym)
4756                   && expr2->value.function.esym->result->attr.dimension));
4757
4758   ss = gfc_walk_expr (expr1);
4759   gcc_assert (ss != gfc_ss_terminator);
4760   gfc_init_se (&se, NULL);
4761   gfc_start_block (&se.pre);
4762   se.want_pointer = 1;
4763
4764   gfc_conv_array_parameter (&se, expr1, ss, 0, NULL, NULL, NULL);
4765
4766   se.direct_byref = 1;
4767   se.ss = gfc_walk_expr (expr2);
4768   gcc_assert (se.ss != gfc_ss_terminator);
4769   gfc_conv_function_expr (&se, expr2);
4770   gfc_add_block_to_block (&se.pre, &se.post);
4771
4772   return gfc_finish_block (&se.pre);
4773 }
4774
4775 /* Determine whether the given EXPR_CONSTANT is a zero initializer.  */
4776
4777 static bool
4778 is_zero_initializer_p (gfc_expr * expr)
4779 {
4780   if (expr->expr_type != EXPR_CONSTANT)
4781     return false;
4782
4783   /* We ignore constants with prescribed memory representations for now.  */
4784   if (expr->representation.string)
4785     return false;
4786
4787   switch (expr->ts.type)
4788     {
4789     case BT_INTEGER:
4790       return mpz_cmp_si (expr->value.integer, 0) == 0;
4791
4792     case BT_REAL:
4793       return mpfr_zero_p (expr->value.real)
4794              && MPFR_SIGN (expr->value.real) >= 0;
4795
4796     case BT_LOGICAL:
4797       return expr->value.logical == 0;
4798
4799     case BT_COMPLEX:
4800       return mpfr_zero_p (mpc_realref (expr->value.complex))
4801              && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
4802              && mpfr_zero_p (mpc_imagref (expr->value.complex))
4803              && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
4804
4805     default:
4806       break;
4807     }
4808   return false;
4809 }
4810
4811 /* Try to efficiently translate array(:) = 0.  Return NULL if this
4812    can't be done.  */
4813
4814 static tree
4815 gfc_trans_zero_assign (gfc_expr * expr)
4816 {
4817   tree dest, len, type;
4818   tree tmp;
4819   gfc_symbol *sym;
4820
4821   sym = expr->symtree->n.sym;
4822   dest = gfc_get_symbol_decl (sym);
4823
4824   type = TREE_TYPE (dest);
4825   if (POINTER_TYPE_P (type))
4826     type = TREE_TYPE (type);
4827   if (!GFC_ARRAY_TYPE_P (type))
4828     return NULL_TREE;
4829
4830   /* Determine the length of the array.  */
4831   len = GFC_TYPE_ARRAY_SIZE (type);
4832   if (!len || TREE_CODE (len) != INTEGER_CST)
4833     return NULL_TREE;
4834
4835   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
4836   len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
4837                      fold_convert (gfc_array_index_type, tmp));
4838
4839   /* If we are zeroing a local array avoid taking its address by emitting
4840      a = {} instead.  */
4841   if (!POINTER_TYPE_P (TREE_TYPE (dest)))
4842     return build2 (MODIFY_EXPR, void_type_node,
4843                    dest, build_constructor (TREE_TYPE (dest), NULL));
4844
4845   /* Convert arguments to the correct types.  */
4846   dest = fold_convert (pvoid_type_node, dest);
4847   len = fold_convert (size_type_node, len);
4848
4849   /* Construct call to __builtin_memset.  */
4850   tmp = build_call_expr_loc (input_location,
4851                          built_in_decls[BUILT_IN_MEMSET],
4852                          3, dest, integer_zero_node, len);
4853   return fold_convert (void_type_node, tmp);
4854 }
4855
4856
4857 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
4858    that constructs the call to __builtin_memcpy.  */
4859
4860 tree
4861 gfc_build_memcpy_call (tree dst, tree src, tree len)
4862 {
4863   tree tmp;
4864
4865   /* Convert arguments to the correct types.  */
4866   if (!POINTER_TYPE_P (TREE_TYPE (dst)))
4867     dst = gfc_build_addr_expr (pvoid_type_node, dst);
4868   else
4869     dst = fold_convert (pvoid_type_node, dst);
4870
4871   if (!POINTER_TYPE_P (TREE_TYPE (src)))
4872     src = gfc_build_addr_expr (pvoid_type_node, src);
4873   else
4874     src = fold_convert (pvoid_type_node, src);
4875
4876   len = fold_convert (size_type_node, len);
4877
4878   /* Construct call to __builtin_memcpy.  */
4879   tmp = build_call_expr_loc (input_location,
4880                          built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
4881   return fold_convert (void_type_node, tmp);
4882 }
4883
4884
4885 /* Try to efficiently translate dst(:) = src(:).  Return NULL if this
4886    can't be done.  EXPR1 is the destination/lhs and EXPR2 is the
4887    source/rhs, both are gfc_full_array_ref_p which have been checked for
4888    dependencies.  */
4889
4890 static tree
4891 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
4892 {
4893   tree dst, dlen, dtype;
4894   tree src, slen, stype;
4895   tree tmp;
4896
4897   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
4898   src = gfc_get_symbol_decl (expr2->symtree->n.sym);
4899
4900   dtype = TREE_TYPE (dst);
4901   if (POINTER_TYPE_P (dtype))
4902     dtype = TREE_TYPE (dtype);
4903   stype = TREE_TYPE (src);
4904   if (POINTER_TYPE_P (stype))
4905     stype = TREE_TYPE (stype);
4906
4907   if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
4908     return NULL_TREE;
4909
4910   /* Determine the lengths of the arrays.  */
4911   dlen = GFC_TYPE_ARRAY_SIZE (dtype);
4912   if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
4913     return NULL_TREE;
4914   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
4915   dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
4916                       fold_convert (gfc_array_index_type, tmp));
4917
4918   slen = GFC_TYPE_ARRAY_SIZE (stype);
4919   if (!slen || TREE_CODE (slen) != INTEGER_CST)
4920     return NULL_TREE;
4921   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
4922   slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
4923                       fold_convert (gfc_array_index_type, tmp));
4924
4925   /* Sanity check that they are the same.  This should always be
4926      the case, as we should already have checked for conformance.  */
4927   if (!tree_int_cst_equal (slen, dlen))
4928     return NULL_TREE;
4929
4930   return gfc_build_memcpy_call (dst, src, dlen);
4931 }
4932
4933
4934 /* Try to efficiently translate array(:) = (/ ... /).  Return NULL if
4935    this can't be done.  EXPR1 is the destination/lhs for which
4936    gfc_full_array_ref_p is true, and EXPR2 is the source/rhs.  */
4937
4938 static tree
4939 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
4940 {
4941   unsigned HOST_WIDE_INT nelem;
4942   tree dst, dtype;
4943   tree src, stype;
4944   tree len;
4945   tree tmp;
4946
4947   nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
4948   if (nelem == 0)
4949     return NULL_TREE;
4950
4951   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
4952   dtype = TREE_TYPE (dst);
4953   if (POINTER_TYPE_P (dtype))
4954     dtype = TREE_TYPE (dtype);
4955   if (!GFC_ARRAY_TYPE_P (dtype))
4956     return NULL_TREE;
4957
4958   /* Determine the lengths of the array.  */
4959   len = GFC_TYPE_ARRAY_SIZE (dtype);
4960   if (!len || TREE_CODE (len) != INTEGER_CST)
4961     return NULL_TREE;
4962
4963   /* Confirm that the constructor is the same size.  */
4964   if (compare_tree_int (len, nelem) != 0)
4965     return NULL_TREE;
4966
4967   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
4968   len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
4969                      fold_convert (gfc_array_index_type, tmp));
4970
4971   stype = gfc_typenode_for_spec (&expr2->ts);
4972   src = gfc_build_constant_array_constructor (expr2, stype);
4973
4974   stype = TREE_TYPE (src);
4975   if (POINTER_TYPE_P (stype))
4976     stype = TREE_TYPE (stype);
4977
4978   return gfc_build_memcpy_call (dst, src, len);
4979 }
4980
4981
4982 /* Subroutine of gfc_trans_assignment that actually scalarizes the
4983    assignment.  EXPR1 is the destination/LHS and EXPR2 is the source/RHS.  */
4984
4985 static tree
4986 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
4987 {
4988   gfc_se lse;
4989   gfc_se rse;
4990   gfc_ss *lss;
4991   gfc_ss *lss_section;
4992   gfc_ss *rss;
4993   gfc_loopinfo loop;
4994   tree tmp;
4995   stmtblock_t block;
4996   stmtblock_t body;
4997   bool l_is_temp;
4998   bool scalar_to_array;
4999   tree string_length;
5000
5001   /* Assignment of the form lhs = rhs.  */
5002   gfc_start_block (&block);
5003
5004   gfc_init_se (&lse, NULL);
5005   gfc_init_se (&rse, NULL);
5006
5007   /* Walk the lhs.  */
5008   lss = gfc_walk_expr (expr1);
5009   rss = NULL;
5010   if (lss != gfc_ss_terminator)
5011     {
5012       /* Allow the scalarizer to workshare array assignments.  */
5013       if (ompws_flags & OMPWS_WORKSHARE_FLAG)
5014         ompws_flags |= OMPWS_SCALARIZER_WS;
5015
5016       /* The assignment needs scalarization.  */
5017       lss_section = lss;
5018
5019       /* Find a non-scalar SS from the lhs.  */
5020       while (lss_section != gfc_ss_terminator
5021              && lss_section->type != GFC_SS_SECTION)
5022         lss_section = lss_section->next;
5023
5024       gcc_assert (lss_section != gfc_ss_terminator);
5025
5026       /* Initialize the scalarizer.  */
5027       gfc_init_loopinfo (&loop);
5028
5029       /* Walk the rhs.  */
5030       rss = gfc_walk_expr (expr2);
5031       if (rss == gfc_ss_terminator)
5032         {
5033           /* The rhs is scalar.  Add a ss for the expression.  */
5034           rss = gfc_get_ss ();
5035           rss->next = gfc_ss_terminator;
5036           rss->type = GFC_SS_SCALAR;
5037           rss->expr = expr2;
5038         }
5039       /* Associate the SS with the loop.  */
5040       gfc_add_ss_to_loop (&loop, lss);
5041       gfc_add_ss_to_loop (&loop, rss);
5042
5043       /* Calculate the bounds of the scalarization.  */
5044       gfc_conv_ss_startstride (&loop);
5045       /* Resolve any data dependencies in the statement.  */
5046       gfc_conv_resolve_dependencies (&loop, lss, rss);
5047       /* Setup the scalarizing loops.  */
5048       gfc_conv_loop_setup (&loop, &expr2->where);
5049
5050       /* Setup the gfc_se structures.  */
5051       gfc_copy_loopinfo_to_se (&lse, &loop);
5052       gfc_copy_loopinfo_to_se (&rse, &loop);
5053
5054       rse.ss = rss;
5055       gfc_mark_ss_chain_used (rss, 1);
5056       if (loop.temp_ss == NULL)
5057         {
5058           lse.ss = lss;
5059           gfc_mark_ss_chain_used (lss, 1);
5060         }
5061       else
5062         {
5063           lse.ss = loop.temp_ss;
5064           gfc_mark_ss_chain_used (lss, 3);
5065           gfc_mark_ss_chain_used (loop.temp_ss, 3);
5066         }
5067
5068       /* Start the scalarized loop body.  */
5069       gfc_start_scalarized_body (&loop, &body);
5070     }
5071   else
5072     gfc_init_block (&body);
5073
5074   l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
5075
5076   /* Translate the expression.  */
5077   gfc_conv_expr (&rse, expr2);
5078
5079   /* Stabilize a string length for temporaries.  */
5080   if (expr2->ts.type == BT_CHARACTER)
5081     string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
5082   else
5083     string_length = NULL_TREE;
5084
5085   if (l_is_temp)
5086     {
5087       gfc_conv_tmp_array_ref (&lse);
5088       gfc_advance_se_ss_chain (&lse);
5089       if (expr2->ts.type == BT_CHARACTER)
5090         lse.string_length = string_length;
5091     }
5092   else
5093     gfc_conv_expr (&lse, expr1);
5094
5095   /* Assignments of scalar derived types with allocatable components
5096      to arrays must be done with a deep copy and the rhs temporary
5097      must have its components deallocated afterwards.  */
5098   scalar_to_array = (expr2->ts.type == BT_DERIVED
5099                        && expr2->ts.u.derived->attr.alloc_comp
5100                        && expr2->expr_type != EXPR_VARIABLE
5101                        && !gfc_is_constant_expr (expr2)
5102                        && expr1->rank && !expr2->rank);
5103   if (scalar_to_array)
5104     {
5105       tmp = gfc_deallocate_alloc_comp (expr2->ts.u.derived, rse.expr, 0);
5106       gfc_add_expr_to_block (&loop.post, tmp);
5107     }
5108
5109   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5110                                  l_is_temp || init_flag,
5111                                  (expr2->expr_type == EXPR_VARIABLE)
5112                                     || scalar_to_array);
5113   gfc_add_expr_to_block (&body, tmp);
5114
5115   if (lss == gfc_ss_terminator)
5116     {
5117       /* Use the scalar assignment as is.  */
5118       gfc_add_block_to_block (&block, &body);
5119     }
5120   else
5121     {
5122       gcc_assert (lse.ss == gfc_ss_terminator
5123                   && rse.ss == gfc_ss_terminator);
5124
5125       if (l_is_temp)
5126         {
5127           gfc_trans_scalarized_loop_boundary (&loop, &body);
5128
5129           /* We need to copy the temporary to the actual lhs.  */
5130           gfc_init_se (&lse, NULL);
5131           gfc_init_se (&rse, NULL);
5132           gfc_copy_loopinfo_to_se (&lse, &loop);
5133           gfc_copy_loopinfo_to_se (&rse, &loop);
5134
5135           rse.ss = loop.temp_ss;
5136           lse.ss = lss;
5137
5138           gfc_conv_tmp_array_ref (&rse);
5139           gfc_advance_se_ss_chain (&rse);
5140           gfc_conv_expr (&lse, expr1);
5141
5142           gcc_assert (lse.ss == gfc_ss_terminator
5143                       && rse.ss == gfc_ss_terminator);
5144
5145           if (expr2->ts.type == BT_CHARACTER)
5146             rse.string_length = string_length;
5147
5148           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5149                                          false, false);
5150           gfc_add_expr_to_block (&body, tmp);
5151         }
5152
5153       /* Generate the copying loops.  */
5154       gfc_trans_scalarizing_loops (&loop, &body);
5155
5156       /* Wrap the whole thing up.  */
5157       gfc_add_block_to_block (&block, &loop.pre);
5158       gfc_add_block_to_block (&block, &loop.post);
5159
5160       gfc_cleanup_loop (&loop);
5161     }
5162
5163   return gfc_finish_block (&block);
5164 }
5165
5166
5167 /* Check whether EXPR is a copyable array.  */
5168
5169 static bool
5170 copyable_array_p (gfc_expr * expr)
5171 {
5172   if (expr->expr_type != EXPR_VARIABLE)
5173     return false;
5174
5175   /* First check it's an array.  */
5176   if (expr->rank < 1 || !expr->ref || expr->ref->next)
5177     return false;
5178
5179   if (!gfc_full_array_ref_p (expr->ref, NULL))
5180     return false;
5181
5182   /* Next check that it's of a simple enough type.  */
5183   switch (expr->ts.type)
5184     {
5185     case BT_INTEGER:
5186     case BT_REAL:
5187     case BT_COMPLEX:
5188     case BT_LOGICAL:
5189       return true;
5190
5191     case BT_CHARACTER:
5192       return false;
5193
5194     case BT_DERIVED:
5195       return !expr->ts.u.derived->attr.alloc_comp;
5196
5197     default:
5198       break;
5199     }
5200
5201   return false;
5202 }
5203
5204 /* Translate an assignment.  */
5205
5206 tree
5207 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
5208 {
5209   tree tmp;
5210
5211   /* Special case a single function returning an array.  */
5212   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5213     {
5214       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5215       if (tmp)
5216         return tmp;
5217     }
5218
5219   /* Special case assigning an array to zero.  */
5220   if (copyable_array_p (expr1)
5221       && is_zero_initializer_p (expr2))
5222     {
5223       tmp = gfc_trans_zero_assign (expr1);
5224       if (tmp)
5225         return tmp;
5226     }
5227
5228   /* Special case copying one array to another.  */
5229   if (copyable_array_p (expr1)
5230       && copyable_array_p (expr2)
5231       && gfc_compare_types (&expr1->ts, &expr2->ts)
5232       && !gfc_check_dependency (expr1, expr2, 0))
5233     {
5234       tmp = gfc_trans_array_copy (expr1, expr2);
5235       if (tmp)
5236         return tmp;
5237     }
5238
5239   /* Special case initializing an array from a constant array constructor.  */
5240   if (copyable_array_p (expr1)
5241       && expr2->expr_type == EXPR_ARRAY
5242       && gfc_compare_types (&expr1->ts, &expr2->ts))
5243     {
5244       tmp = gfc_trans_array_constructor_copy (expr1, expr2);
5245       if (tmp)
5246         return tmp;
5247     }
5248
5249   /* Fallback to the scalarizer to generate explicit loops.  */
5250   return gfc_trans_assignment_1 (expr1, expr2, init_flag);
5251 }
5252
5253 tree
5254 gfc_trans_init_assign (gfc_code * code)
5255 {
5256   return gfc_trans_assignment (code->expr1, code->expr2, true);
5257 }
5258
5259 tree
5260 gfc_trans_assign (gfc_code * code)
5261 {
5262   return gfc_trans_assignment (code->expr1, code->expr2, false);
5263 }