OSDN Git Service

2007-07-23 Christopher D. Rickett <crickett@lanl.gov>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-expr.c
1 /* Expression translation
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software
3    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 2, 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 COPYING.  If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301, USA.  */
23
24 /* trans-expr.c-- generate GENERIC trees for gfc_expr.  */
25
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tree.h"
30 #include "convert.h"
31 #include "ggc.h"
32 #include "toplev.h"
33 #include "real.h"
34 #include "tree-gimple.h"
35 #include "langhooks.h"
36 #include "flags.h"
37 #include "gfortran.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 int 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_expr (&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 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)
151 {
152   tree present;
153   tree tmp;
154
155   present = gfc_conv_expr_present (arg->symtree->n.sym);
156   tmp = build3 (COND_EXPR, TREE_TYPE (se->expr), present, se->expr,
157                 fold_convert (TREE_TYPE (se->expr), integer_zero_node));
158
159   tmp = gfc_evaluate_now (tmp, &se->pre);
160   se->expr = tmp;
161   if (ts.type == BT_CHARACTER)
162     {
163       tmp = build_int_cst (gfc_charlen_type_node, 0);
164       tmp = build3 (COND_EXPR, gfc_charlen_type_node, present,
165                     se->string_length, tmp);
166       tmp = gfc_evaluate_now (tmp, &se->pre);
167       se->string_length = tmp;
168     }
169   return;
170 }
171
172
173 /* Get the character length of an expression, looking through gfc_refs
174    if necessary.  */
175
176 tree
177 gfc_get_expr_charlen (gfc_expr *e)
178 {
179   gfc_ref *r;
180   tree length;
181
182   gcc_assert (e->expr_type == EXPR_VARIABLE 
183               && e->ts.type == BT_CHARACTER);
184   
185   length = NULL; /* To silence compiler warning.  */
186
187   /* First candidate: if the variable is of type CHARACTER, the
188      expression's length could be the length of the character
189      variable.  */
190   if (e->symtree->n.sym->ts.type == BT_CHARACTER)
191     length = e->symtree->n.sym->ts.cl->backend_decl;
192
193   /* Look through the reference chain for component references.  */
194   for (r = e->ref; r; r = r->next)
195     {
196       switch (r->type)
197         {
198         case REF_COMPONENT:
199           if (r->u.c.component->ts.type == BT_CHARACTER)
200             length = r->u.c.component->ts.cl->backend_decl;
201           break;
202
203         case REF_ARRAY:
204           /* Do nothing.  */
205           break;
206
207         default:
208           /* We should never got substring references here.  These will be
209              broken down by the scalarizer.  */
210           gcc_unreachable ();
211         }
212     }
213
214   gcc_assert (length != NULL);
215   return length;
216 }
217
218   
219
220 /* Generate code to initialize a string length variable. Returns the
221    value.  */
222
223 void
224 gfc_trans_init_string_length (gfc_charlen * cl, stmtblock_t * pblock)
225 {
226   gfc_se se;
227   tree tmp;
228
229   gfc_init_se (&se, NULL);
230   gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
231   se.expr = fold_build2 (MAX_EXPR, gfc_charlen_type_node, se.expr,
232                          build_int_cst (gfc_charlen_type_node, 0));
233   gfc_add_block_to_block (pblock, &se.pre);
234
235   tmp = cl->backend_decl;
236   gfc_add_modify_expr (pblock, tmp, se.expr);
237 }
238
239
240 static void
241 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
242                     const char *name, locus *where)
243 {
244   tree tmp;
245   tree type;
246   tree var;
247   tree fault;
248   gfc_se start;
249   gfc_se end;
250   char *msg;
251
252   type = gfc_get_character_type (kind, ref->u.ss.length);
253   type = build_pointer_type (type);
254
255   var = NULL_TREE;
256   gfc_init_se (&start, se);
257   gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
258   gfc_add_block_to_block (&se->pre, &start.pre);
259
260   if (integer_onep (start.expr))
261     gfc_conv_string_parameter (se);
262   else
263     {
264       /* Avoid multiple evaluation of substring start.  */
265       if (!CONSTANT_CLASS_P (start.expr) && !DECL_P (start.expr))
266         start.expr = gfc_evaluate_now (start.expr, &se->pre);
267
268       /* Change the start of the string.  */
269       if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
270         tmp = se->expr;
271       else
272         tmp = build_fold_indirect_ref (se->expr);
273       tmp = gfc_build_array_ref (tmp, start.expr);
274       se->expr = gfc_build_addr_expr (type, tmp);
275     }
276
277   /* Length = end + 1 - start.  */
278   gfc_init_se (&end, se);
279   if (ref->u.ss.end == NULL)
280     end.expr = se->string_length;
281   else
282     {
283       gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
284       gfc_add_block_to_block (&se->pre, &end.pre);
285     }
286   if (!CONSTANT_CLASS_P (end.expr) && !DECL_P (end.expr))
287     end.expr = gfc_evaluate_now (end.expr, &se->pre);
288
289   if (flag_bounds_check)
290     {
291       tree nonempty = fold_build2 (LE_EXPR, boolean_type_node,
292                                    start.expr, end.expr);
293
294       /* Check lower bound.  */
295       fault = fold_build2 (LT_EXPR, boolean_type_node, start.expr,
296                            build_int_cst (gfc_charlen_type_node, 1));
297       fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
298                            nonempty, fault);
299       if (name)
300         asprintf (&msg, "Substring out of bounds: lower bound of '%s' "
301                   "is less than one", name);
302       else
303         asprintf (&msg, "Substring out of bounds: lower bound "
304                   "is less than one");
305       gfc_trans_runtime_check (fault, msg, &se->pre, where);
306       gfc_free (msg);
307
308       /* Check upper bound.  */
309       fault = fold_build2 (GT_EXPR, boolean_type_node, end.expr,
310                            se->string_length);
311       fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
312                            nonempty, fault);
313       if (name)
314         asprintf (&msg, "Substring out of bounds: upper bound of '%s' "
315                   "exceeds string length", name);
316       else
317         asprintf (&msg, "Substring out of bounds: upper bound "
318                   "exceeds string length");
319       gfc_trans_runtime_check (fault, msg, &se->pre, where);
320       gfc_free (msg);
321     }
322
323   tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node,
324                      build_int_cst (gfc_charlen_type_node, 1),
325                      start.expr);
326   tmp = fold_build2 (PLUS_EXPR, gfc_charlen_type_node, end.expr, tmp);
327   tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
328                      build_int_cst (gfc_charlen_type_node, 0));
329   se->string_length = tmp;
330 }
331
332
333 /* Convert a derived type component reference.  */
334
335 static void
336 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
337 {
338   gfc_component *c;
339   tree tmp;
340   tree decl;
341   tree field;
342
343   c = ref->u.c.component;
344
345   gcc_assert (c->backend_decl);
346
347   field = c->backend_decl;
348   gcc_assert (TREE_CODE (field) == FIELD_DECL);
349   decl = se->expr;
350   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
351
352   se->expr = tmp;
353
354   if (c->ts.type == BT_CHARACTER)
355     {
356       tmp = c->ts.cl->backend_decl;
357       /* Components must always be constant length.  */
358       gcc_assert (tmp && INTEGER_CST_P (tmp));
359       se->string_length = tmp;
360     }
361
362   if (c->pointer && c->dimension == 0 && c->ts.type != BT_CHARACTER)
363     se->expr = build_fold_indirect_ref (se->expr);
364 }
365
366
367 /* Return the contents of a variable. Also handles reference/pointer
368    variables (all Fortran pointer references are implicit).  */
369
370 static void
371 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
372 {
373   gfc_ref *ref;
374   gfc_symbol *sym;
375   tree parent_decl;
376   int parent_flag;
377   bool return_value;
378   bool alternate_entry;
379   bool entry_master;
380
381   sym = expr->symtree->n.sym;
382   if (se->ss != NULL)
383     {
384       /* Check that something hasn't gone horribly wrong.  */
385       gcc_assert (se->ss != gfc_ss_terminator);
386       gcc_assert (se->ss->expr == expr);
387
388       /* A scalarized term.  We already know the descriptor.  */
389       se->expr = se->ss->data.info.descriptor;
390       se->string_length = se->ss->string_length;
391       for (ref = se->ss->data.info.ref; ref; ref = ref->next)
392         if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
393           break;
394     }
395   else
396     {
397       tree se_expr = NULL_TREE;
398
399       se->expr = gfc_get_symbol_decl (sym);
400
401       /* Deal with references to a parent results or entries by storing
402          the current_function_decl and moving to the parent_decl.  */
403       return_value = sym->attr.function && sym->result == sym;
404       alternate_entry = sym->attr.function && sym->attr.entry
405                         && sym->result == sym;
406       entry_master = sym->attr.result
407                      && sym->ns->proc_name->attr.entry_master
408                      && !gfc_return_by_reference (sym->ns->proc_name);
409       parent_decl = DECL_CONTEXT (current_function_decl);
410
411       if ((se->expr == parent_decl && return_value)
412            || (sym->ns && sym->ns->proc_name
413                && parent_decl
414                && sym->ns->proc_name->backend_decl == parent_decl
415                && (alternate_entry || entry_master)))
416         parent_flag = 1;
417       else
418         parent_flag = 0;
419
420       /* Special case for assigning the return value of a function.
421          Self recursive functions must have an explicit return value.  */
422       if (return_value && (se->expr == current_function_decl || parent_flag))
423         se_expr = gfc_get_fake_result_decl (sym, parent_flag);
424
425       /* Similarly for alternate entry points.  */
426       else if (alternate_entry 
427                && (sym->ns->proc_name->backend_decl == current_function_decl
428                    || parent_flag))
429         {
430           gfc_entry_list *el = NULL;
431
432           for (el = sym->ns->entries; el; el = el->next)
433             if (sym == el->sym)
434               {
435                 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
436                 break;
437               }
438         }
439
440       else if (entry_master
441                && (sym->ns->proc_name->backend_decl == current_function_decl
442                    || parent_flag))
443         se_expr = gfc_get_fake_result_decl (sym, parent_flag);
444
445       if (se_expr)
446         se->expr = se_expr;
447
448       /* Procedure actual arguments.  */
449       else if (sym->attr.flavor == FL_PROCEDURE
450                && se->expr != current_function_decl)
451         {
452           gcc_assert (se->want_pointer);
453           if (!sym->attr.dummy)
454             {
455               gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
456               se->expr = build_fold_addr_expr (se->expr);
457             }
458           return;
459         }
460
461
462       /* Dereference the expression, where needed. Since characters
463          are entirely different from other types, they are treated 
464          separately.  */
465       if (sym->ts.type == BT_CHARACTER)
466         {
467           /* Dereference character pointer dummy arguments
468              or results.  */
469           if ((sym->attr.pointer || sym->attr.allocatable)
470               && (sym->attr.dummy
471                   || sym->attr.function
472                   || sym->attr.result))
473             se->expr = build_fold_indirect_ref (se->expr);
474
475         }
476       else if (!sym->attr.value)
477         {
478           /* Dereference non-character scalar dummy arguments.  */
479           if (sym->attr.dummy && !sym->attr.dimension)
480             se->expr = build_fold_indirect_ref (se->expr);
481
482           /* Dereference scalar hidden result.  */
483           if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
484               && (sym->attr.function || sym->attr.result)
485               && !sym->attr.dimension && !sym->attr.pointer)
486             se->expr = build_fold_indirect_ref (se->expr);
487
488           /* Dereference non-character pointer variables. 
489              These must be dummies, results, or scalars.  */
490           if ((sym->attr.pointer || sym->attr.allocatable)
491               && (sym->attr.dummy
492                   || sym->attr.function
493                   || sym->attr.result
494                   || !sym->attr.dimension))
495             se->expr = build_fold_indirect_ref (se->expr);
496         }
497
498       ref = expr->ref;
499     }
500
501   /* For character variables, also get the length.  */
502   if (sym->ts.type == BT_CHARACTER)
503     {
504       /* If the character length of an entry isn't set, get the length from
505          the master function instead.  */
506       if (sym->attr.entry && !sym->ts.cl->backend_decl)
507         se->string_length = sym->ns->proc_name->ts.cl->backend_decl;
508       else
509         se->string_length = sym->ts.cl->backend_decl;
510       gcc_assert (se->string_length);
511     }
512
513   while (ref)
514     {
515       switch (ref->type)
516         {
517         case REF_ARRAY:
518           /* Return the descriptor if that's what we want and this is an array
519              section reference.  */
520           if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
521             return;
522 /* TODO: Pointers to single elements of array sections, eg elemental subs.  */
523           /* Return the descriptor for array pointers and allocations.  */
524           if (se->want_pointer
525               && ref->next == NULL && (se->descriptor_only))
526             return;
527
528           gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
529           /* Return a pointer to an element.  */
530           break;
531
532         case REF_COMPONENT:
533           gfc_conv_component_ref (se, ref);
534           break;
535
536         case REF_SUBSTRING:
537           gfc_conv_substring (se, ref, expr->ts.kind,
538                               expr->symtree->name, &expr->where);
539           break;
540
541         default:
542           gcc_unreachable ();
543           break;
544         }
545       ref = ref->next;
546     }
547   /* Pointer assignment, allocation or pass by reference.  Arrays are handled
548      separately.  */
549   if (se->want_pointer)
550     {
551       if (expr->ts.type == BT_CHARACTER)
552         gfc_conv_string_parameter (se);
553       else 
554         se->expr = build_fold_addr_expr (se->expr);
555     }
556 }
557
558
559 /* Unary ops are easy... Or they would be if ! was a valid op.  */
560
561 static void
562 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
563 {
564   gfc_se operand;
565   tree type;
566
567   gcc_assert (expr->ts.type != BT_CHARACTER);
568   /* Initialize the operand.  */
569   gfc_init_se (&operand, se);
570   gfc_conv_expr_val (&operand, expr->value.op.op1);
571   gfc_add_block_to_block (&se->pre, &operand.pre);
572
573   type = gfc_typenode_for_spec (&expr->ts);
574
575   /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
576      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
577      All other unary operators have an equivalent GIMPLE unary operator.  */
578   if (code == TRUTH_NOT_EXPR)
579     se->expr = build2 (EQ_EXPR, type, operand.expr,
580                        build_int_cst (type, 0));
581   else
582     se->expr = build1 (code, type, operand.expr);
583
584 }
585
586 /* Expand power operator to optimal multiplications when a value is raised
587    to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
588    Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
589    Programming", 3rd Edition, 1998.  */
590
591 /* This code is mostly duplicated from expand_powi in the backend.
592    We establish the "optimal power tree" lookup table with the defined size.
593    The items in the table are the exponents used to calculate the index
594    exponents. Any integer n less than the value can get an "addition chain",
595    with the first node being one.  */
596 #define POWI_TABLE_SIZE 256
597
598 /* The table is from builtins.c.  */
599 static const unsigned char powi_table[POWI_TABLE_SIZE] =
600   {
601       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
602       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
603       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
604      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
605      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
606      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
607      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
608      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
609      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
610      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
611      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
612      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
613      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
614      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
615      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
616      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
617      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
618      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
619      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
620      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
621      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
622      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
623      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
624      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
625      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
626     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
627     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
628     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
629     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
630     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
631     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
632     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
633   };
634
635 /* If n is larger than lookup table's max index, we use the "window 
636    method".  */
637 #define POWI_WINDOW_SIZE 3
638
639 /* Recursive function to expand the power operator. The temporary 
640    values are put in tmpvar. The function returns tmpvar[1] ** n.  */
641 static tree
642 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
643 {
644   tree op0;
645   tree op1;
646   tree tmp;
647   int digit;
648
649   if (n < POWI_TABLE_SIZE)
650     {
651       if (tmpvar[n])
652         return tmpvar[n];
653
654       op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
655       op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
656     }
657   else if (n & 1)
658     {
659       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
660       op0 = gfc_conv_powi (se, n - digit, tmpvar);
661       op1 = gfc_conv_powi (se, digit, tmpvar);
662     }
663   else
664     {
665       op0 = gfc_conv_powi (se, n >> 1, tmpvar);
666       op1 = op0;
667     }
668
669   tmp = fold_build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1);
670   tmp = gfc_evaluate_now (tmp, &se->pre);
671
672   if (n < POWI_TABLE_SIZE)
673     tmpvar[n] = tmp;
674
675   return tmp;
676 }
677
678
679 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
680    return 1. Else return 0 and a call to runtime library functions
681    will have to be built.  */
682 static int
683 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
684 {
685   tree cond;
686   tree tmp;
687   tree type;
688   tree vartmp[POWI_TABLE_SIZE];
689   HOST_WIDE_INT m;
690   unsigned HOST_WIDE_INT n;
691   int sgn;
692
693   /* If exponent is too large, we won't expand it anyway, so don't bother
694      with large integer values.  */
695   if (!double_int_fits_in_shwi_p (TREE_INT_CST (rhs)))
696     return 0;
697
698   m = double_int_to_shwi (TREE_INT_CST (rhs));
699   /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
700      of the asymmetric range of the integer type.  */
701   n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
702   
703   type = TREE_TYPE (lhs);
704   sgn = tree_int_cst_sgn (rhs);
705
706   if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
707        || optimize_size) && (m > 2 || m < -1))
708     return 0;
709
710   /* rhs == 0  */
711   if (sgn == 0)
712     {
713       se->expr = gfc_build_const (type, integer_one_node);
714       return 1;
715     }
716
717   /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1.  */
718   if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
719     {
720       tmp = build2 (EQ_EXPR, boolean_type_node, lhs,
721                     build_int_cst (TREE_TYPE (lhs), -1));
722       cond = build2 (EQ_EXPR, boolean_type_node, lhs,
723                      build_int_cst (TREE_TYPE (lhs), 1));
724
725       /* If rhs is even,
726          result = (lhs == 1 || lhs == -1) ? 1 : 0.  */
727       if ((n & 1) == 0)
728         {
729           tmp = build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
730           se->expr = build3 (COND_EXPR, type, tmp, build_int_cst (type, 1),
731                              build_int_cst (type, 0));
732           return 1;
733         }
734       /* If rhs is odd,
735          result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0.  */
736       tmp = build3 (COND_EXPR, type, tmp, build_int_cst (type, -1),
737                     build_int_cst (type, 0));
738       se->expr = build3 (COND_EXPR, type, cond, build_int_cst (type, 1), tmp);
739       return 1;
740     }
741
742   memset (vartmp, 0, sizeof (vartmp));
743   vartmp[1] = lhs;
744   if (sgn == -1)
745     {
746       tmp = gfc_build_const (type, integer_one_node);
747       vartmp[1] = build2 (RDIV_EXPR, type, tmp, vartmp[1]);
748     }
749
750   se->expr = gfc_conv_powi (se, n, vartmp);
751
752   return 1;
753 }
754
755
756 /* Power op (**).  Constant integer exponent has special handling.  */
757
758 static void
759 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
760 {
761   tree gfc_int4_type_node;
762   int kind;
763   int ikind;
764   gfc_se lse;
765   gfc_se rse;
766   tree fndecl;
767
768   gfc_init_se (&lse, se);
769   gfc_conv_expr_val (&lse, expr->value.op.op1);
770   lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
771   gfc_add_block_to_block (&se->pre, &lse.pre);
772
773   gfc_init_se (&rse, se);
774   gfc_conv_expr_val (&rse, expr->value.op.op2);
775   gfc_add_block_to_block (&se->pre, &rse.pre);
776
777   if (expr->value.op.op2->ts.type == BT_INTEGER
778       && expr->value.op.op2->expr_type == EXPR_CONSTANT)
779     if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
780       return;
781
782   gfc_int4_type_node = gfc_get_int_type (4);
783
784   kind = expr->value.op.op1->ts.kind;
785   switch (expr->value.op.op2->ts.type)
786     {
787     case BT_INTEGER:
788       ikind = expr->value.op.op2->ts.kind;
789       switch (ikind)
790         {
791         case 1:
792         case 2:
793           rse.expr = convert (gfc_int4_type_node, rse.expr);
794           /* Fall through.  */
795
796         case 4:
797           ikind = 0;
798           break;
799           
800         case 8:
801           ikind = 1;
802           break;
803
804         case 16:
805           ikind = 2;
806           break;
807
808         default:
809           gcc_unreachable ();
810         }
811       switch (kind)
812         {
813         case 1:
814         case 2:
815           if (expr->value.op.op1->ts.type == BT_INTEGER)
816             lse.expr = convert (gfc_int4_type_node, lse.expr);
817           else
818             gcc_unreachable ();
819           /* Fall through.  */
820
821         case 4:
822           kind = 0;
823           break;
824           
825         case 8:
826           kind = 1;
827           break;
828
829         case 10:
830           kind = 2;
831           break;
832
833         case 16:
834           kind = 3;
835           break;
836
837         default:
838           gcc_unreachable ();
839         }
840       
841       switch (expr->value.op.op1->ts.type)
842         {
843         case BT_INTEGER:
844           if (kind == 3) /* Case 16 was not handled properly above.  */
845             kind = 2;
846           fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
847           break;
848
849         case BT_REAL:
850           /* Use builtins for real ** int4.  */
851           if (ikind == 0)
852             {
853               switch (kind)
854                 {
855                 case 0:
856                   fndecl = built_in_decls[BUILT_IN_POWIF];
857                   break;
858                 
859                 case 1:
860                   fndecl = built_in_decls[BUILT_IN_POWI];
861                   break;
862
863                 case 2:
864                 case 3:
865                   fndecl = built_in_decls[BUILT_IN_POWIL];
866                   break;
867
868                 default:
869                   gcc_unreachable ();
870                 }
871             }
872           else
873             fndecl = gfor_fndecl_math_powi[kind][ikind].real;
874           break;
875
876         case BT_COMPLEX:
877           fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
878           break;
879
880         default:
881           gcc_unreachable ();
882         }
883       break;
884
885     case BT_REAL:
886       switch (kind)
887         {
888         case 4:
889           fndecl = built_in_decls[BUILT_IN_POWF];
890           break;
891         case 8:
892           fndecl = built_in_decls[BUILT_IN_POW];
893           break;
894         case 10:
895         case 16:
896           fndecl = built_in_decls[BUILT_IN_POWL];
897           break;
898         default:
899           gcc_unreachable ();
900         }
901       break;
902
903     case BT_COMPLEX:
904       switch (kind)
905         {
906         case 4:
907           fndecl = gfor_fndecl_math_cpowf;
908           break;
909         case 8:
910           fndecl = gfor_fndecl_math_cpow;
911           break;
912         case 10:
913           fndecl = gfor_fndecl_math_cpowl10;
914           break;
915         case 16:
916           fndecl = gfor_fndecl_math_cpowl16;
917           break;
918         default:
919           gcc_unreachable ();
920         }
921       break;
922
923     default:
924       gcc_unreachable ();
925       break;
926     }
927
928   se->expr = build_call_expr (fndecl, 2, lse.expr, rse.expr);
929 }
930
931
932 /* Generate code to allocate a string temporary.  */
933
934 tree
935 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
936 {
937   tree var;
938   tree tmp;
939
940   gcc_assert (TREE_TYPE (len) == gfc_charlen_type_node);
941
942   if (gfc_can_put_var_on_stack (len))
943     {
944       /* Create a temporary variable to hold the result.  */
945       tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
946                          build_int_cst (gfc_charlen_type_node, 1));
947       tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
948       tmp = build_array_type (gfc_character1_type_node, tmp);
949       var = gfc_create_var (tmp, "str");
950       var = gfc_build_addr_expr (type, var);
951     }
952   else
953     {
954       /* Allocate a temporary to hold the result.  */
955       var = gfc_create_var (type, "pstr");
956       tmp = gfc_call_malloc (&se->pre, type, len);
957       gfc_add_modify_expr (&se->pre, var, tmp);
958
959       /* Free the temporary afterwards.  */
960       tmp = gfc_call_free (convert (pvoid_type_node, var));
961       gfc_add_expr_to_block (&se->post, tmp);
962     }
963
964   return var;
965 }
966
967
968 /* Handle a string concatenation operation.  A temporary will be allocated to
969    hold the result.  */
970
971 static void
972 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
973 {
974   gfc_se lse;
975   gfc_se rse;
976   tree len;
977   tree type;
978   tree var;
979   tree tmp;
980
981   gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
982           && expr->value.op.op2->ts.type == BT_CHARACTER);
983
984   gfc_init_se (&lse, se);
985   gfc_conv_expr (&lse, expr->value.op.op1);
986   gfc_conv_string_parameter (&lse);
987   gfc_init_se (&rse, se);
988   gfc_conv_expr (&rse, expr->value.op.op2);
989   gfc_conv_string_parameter (&rse);
990
991   gfc_add_block_to_block (&se->pre, &lse.pre);
992   gfc_add_block_to_block (&se->pre, &rse.pre);
993
994   type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
995   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
996   if (len == NULL_TREE)
997     {
998       len = fold_build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
999                          lse.string_length, rse.string_length);
1000     }
1001
1002   type = build_pointer_type (type);
1003
1004   var = gfc_conv_string_tmp (se, type, len);
1005
1006   /* Do the actual concatenation.  */
1007   tmp = build_call_expr (gfor_fndecl_concat_string, 6,
1008                          len, var,
1009                          lse.string_length, lse.expr,
1010                          rse.string_length, rse.expr);
1011   gfc_add_expr_to_block (&se->pre, tmp);
1012
1013   /* Add the cleanup for the operands.  */
1014   gfc_add_block_to_block (&se->pre, &rse.post);
1015   gfc_add_block_to_block (&se->pre, &lse.post);
1016
1017   se->expr = var;
1018   se->string_length = len;
1019 }
1020
1021 /* Translates an op expression. Common (binary) cases are handled by this
1022    function, others are passed on. Recursion is used in either case.
1023    We use the fact that (op1.ts == op2.ts) (except for the power
1024    operator **).
1025    Operators need no special handling for scalarized expressions as long as
1026    they call gfc_conv_simple_val to get their operands.
1027    Character strings get special handling.  */
1028
1029 static void
1030 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
1031 {
1032   enum tree_code code;
1033   gfc_se lse;
1034   gfc_se rse;
1035   tree type;
1036   tree tmp;
1037   int lop;
1038   int checkstring;
1039
1040   checkstring = 0;
1041   lop = 0;
1042   switch (expr->value.op.operator)
1043     {
1044     case INTRINSIC_UPLUS:
1045     case INTRINSIC_PARENTHESES:
1046       gfc_conv_expr (se, expr->value.op.op1);
1047       return;
1048
1049     case INTRINSIC_UMINUS:
1050       gfc_conv_unary_op (NEGATE_EXPR, se, expr);
1051       return;
1052
1053     case INTRINSIC_NOT:
1054       gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
1055       return;
1056
1057     case INTRINSIC_PLUS:
1058       code = PLUS_EXPR;
1059       break;
1060
1061     case INTRINSIC_MINUS:
1062       code = MINUS_EXPR;
1063       break;
1064
1065     case INTRINSIC_TIMES:
1066       code = MULT_EXPR;
1067       break;
1068
1069     case INTRINSIC_DIVIDE:
1070       /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1071          an integer, we must round towards zero, so we use a
1072          TRUNC_DIV_EXPR.  */
1073       if (expr->ts.type == BT_INTEGER)
1074         code = TRUNC_DIV_EXPR;
1075       else
1076         code = RDIV_EXPR;
1077       break;
1078
1079     case INTRINSIC_POWER:
1080       gfc_conv_power_op (se, expr);
1081       return;
1082
1083     case INTRINSIC_CONCAT:
1084       gfc_conv_concat_op (se, expr);
1085       return;
1086
1087     case INTRINSIC_AND:
1088       code = TRUTH_ANDIF_EXPR;
1089       lop = 1;
1090       break;
1091
1092     case INTRINSIC_OR:
1093       code = TRUTH_ORIF_EXPR;
1094       lop = 1;
1095       break;
1096
1097       /* EQV and NEQV only work on logicals, but since we represent them
1098          as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
1099     case INTRINSIC_EQ:
1100     case INTRINSIC_EQ_OS:
1101     case INTRINSIC_EQV:
1102       code = EQ_EXPR;
1103       checkstring = 1;
1104       lop = 1;
1105       break;
1106
1107     case INTRINSIC_NE:
1108     case INTRINSIC_NE_OS:
1109     case INTRINSIC_NEQV:
1110       code = NE_EXPR;
1111       checkstring = 1;
1112       lop = 1;
1113       break;
1114
1115     case INTRINSIC_GT:
1116     case INTRINSIC_GT_OS:
1117       code = GT_EXPR;
1118       checkstring = 1;
1119       lop = 1;
1120       break;
1121
1122     case INTRINSIC_GE:
1123     case INTRINSIC_GE_OS:
1124       code = GE_EXPR;
1125       checkstring = 1;
1126       lop = 1;
1127       break;
1128
1129     case INTRINSIC_LT:
1130     case INTRINSIC_LT_OS:
1131       code = LT_EXPR;
1132       checkstring = 1;
1133       lop = 1;
1134       break;
1135
1136     case INTRINSIC_LE:
1137     case INTRINSIC_LE_OS:
1138       code = LE_EXPR;
1139       checkstring = 1;
1140       lop = 1;
1141       break;
1142
1143     case INTRINSIC_USER:
1144     case INTRINSIC_ASSIGN:
1145       /* These should be converted into function calls by the frontend.  */
1146       gcc_unreachable ();
1147
1148     default:
1149       fatal_error ("Unknown intrinsic op");
1150       return;
1151     }
1152
1153   /* The only exception to this is **, which is handled separately anyway.  */
1154   gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
1155
1156   if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
1157     checkstring = 0;
1158
1159   /* lhs */
1160   gfc_init_se (&lse, se);
1161   gfc_conv_expr (&lse, expr->value.op.op1);
1162   gfc_add_block_to_block (&se->pre, &lse.pre);
1163
1164   /* rhs */
1165   gfc_init_se (&rse, se);
1166   gfc_conv_expr (&rse, expr->value.op.op2);
1167   gfc_add_block_to_block (&se->pre, &rse.pre);
1168
1169   if (checkstring)
1170     {
1171       gfc_conv_string_parameter (&lse);
1172       gfc_conv_string_parameter (&rse);
1173
1174       lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
1175                                            rse.string_length, rse.expr);
1176       rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
1177       gfc_add_block_to_block (&lse.post, &rse.post);
1178     }
1179
1180   type = gfc_typenode_for_spec (&expr->ts);
1181
1182   if (lop)
1183     {
1184       /* The result of logical ops is always boolean_type_node.  */
1185       tmp = fold_build2 (code, type, lse.expr, rse.expr);
1186       se->expr = convert (type, tmp);
1187     }
1188   else
1189     se->expr = fold_build2 (code, type, lse.expr, rse.expr);
1190
1191   /* Add the post blocks.  */
1192   gfc_add_block_to_block (&se->post, &rse.post);
1193   gfc_add_block_to_block (&se->post, &lse.post);
1194 }
1195
1196 /* If a string's length is one, we convert it to a single character.  */
1197
1198 static tree
1199 gfc_to_single_character (tree len, tree str)
1200 {
1201   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
1202
1203   if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
1204     && TREE_INT_CST_HIGH (len) == 0)
1205     {
1206       str = fold_convert (pchar_type_node, str);
1207       return build_fold_indirect_ref (str);
1208     }
1209
1210   return NULL_TREE;
1211 }
1212
1213 /* Compare two strings. If they are all single characters, the result is the
1214    subtraction of them. Otherwise, we build a library call.  */
1215
1216 tree
1217 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2)
1218 {
1219   tree sc1;
1220   tree sc2;
1221   tree type;
1222   tree tmp;
1223
1224   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
1225   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
1226
1227   type = gfc_get_int_type (gfc_default_integer_kind);
1228
1229   sc1 = gfc_to_single_character (len1, str1);
1230   sc2 = gfc_to_single_character (len2, str2);
1231
1232   /* Deal with single character specially.  */
1233   if (sc1 != NULL_TREE && sc2 != NULL_TREE)
1234     {
1235       sc1 = fold_convert (type, sc1);
1236       sc2 = fold_convert (type, sc2);
1237       tmp = fold_build2 (MINUS_EXPR, type, sc1, sc2);
1238     }
1239    else
1240      /* Build a call for the comparison.  */
1241      tmp = build_call_expr (gfor_fndecl_compare_string, 4,
1242                             len1, str1, len2, str2);
1243   return tmp;
1244 }
1245
1246 static void
1247 gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
1248 {
1249   tree tmp;
1250
1251   if (sym->attr.dummy)
1252     {
1253       tmp = gfc_get_symbol_decl (sym);
1254       gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1255               && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
1256     }
1257   else
1258     {
1259       if (!sym->backend_decl)
1260         sym->backend_decl = gfc_get_extern_function_decl (sym);
1261
1262       tmp = sym->backend_decl;
1263       if (sym->attr.cray_pointee)
1264         tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
1265                        gfc_get_symbol_decl (sym->cp_pointer));
1266       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1267         {
1268           gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1269           tmp = build_fold_addr_expr (tmp);
1270         }
1271     }
1272   se->expr = tmp;
1273 }
1274
1275
1276 /* Translate the call for an elemental subroutine call used in an operator
1277    assignment.  This is a simplified version of gfc_conv_function_call.  */
1278
1279 tree
1280 gfc_conv_operator_assign (gfc_se *lse, gfc_se *rse, gfc_symbol *sym)
1281 {
1282   tree args;
1283   tree tmp;
1284   gfc_se se;
1285   stmtblock_t block;
1286
1287   /* Only elemental subroutines with two arguments.  */
1288   gcc_assert (sym->attr.elemental && sym->attr.subroutine);
1289   gcc_assert (sym->formal->next->next == NULL);
1290
1291   gfc_init_block (&block);
1292
1293   gfc_add_block_to_block (&block, &lse->pre);
1294   gfc_add_block_to_block (&block, &rse->pre);
1295
1296   /* Build the argument list for the call, including hidden string lengths.  */
1297   args = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (lse->expr));
1298   args = gfc_chainon_list (args, build_fold_addr_expr (rse->expr));
1299   if (lse->string_length != NULL_TREE)
1300     args = gfc_chainon_list (args, lse->string_length);
1301   if (rse->string_length != NULL_TREE)
1302     args = gfc_chainon_list (args, rse->string_length);    
1303
1304   /* Build the function call.  */
1305   gfc_init_se (&se, NULL);
1306   gfc_conv_function_val (&se, sym);
1307   tmp = TREE_TYPE (TREE_TYPE (TREE_TYPE (se.expr)));
1308   tmp = build_call_list (tmp, se.expr, args);
1309   gfc_add_expr_to_block (&block, tmp);
1310
1311   gfc_add_block_to_block (&block, &lse->post);
1312   gfc_add_block_to_block (&block, &rse->post);
1313
1314   return gfc_finish_block (&block);
1315 }
1316
1317
1318 /* Initialize MAPPING.  */
1319
1320 void
1321 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
1322 {
1323   mapping->syms = NULL;
1324   mapping->charlens = NULL;
1325 }
1326
1327
1328 /* Free all memory held by MAPPING (but not MAPPING itself).  */
1329
1330 void
1331 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
1332 {
1333   gfc_interface_sym_mapping *sym;
1334   gfc_interface_sym_mapping *nextsym;
1335   gfc_charlen *cl;
1336   gfc_charlen *nextcl;
1337
1338   for (sym = mapping->syms; sym; sym = nextsym)
1339     {
1340       nextsym = sym->next;
1341       gfc_free_symbol (sym->new->n.sym);
1342       gfc_free (sym->new);
1343       gfc_free (sym);
1344     }
1345   for (cl = mapping->charlens; cl; cl = nextcl)
1346     {
1347       nextcl = cl->next;
1348       gfc_free_expr (cl->length);
1349       gfc_free (cl);
1350     }
1351 }
1352
1353
1354 /* Return a copy of gfc_charlen CL.  Add the returned structure to
1355    MAPPING so that it will be freed by gfc_free_interface_mapping.  */
1356
1357 static gfc_charlen *
1358 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
1359                                    gfc_charlen * cl)
1360 {
1361   gfc_charlen *new;
1362
1363   new = gfc_get_charlen ();
1364   new->next = mapping->charlens;
1365   new->length = gfc_copy_expr (cl->length);
1366
1367   mapping->charlens = new;
1368   return new;
1369 }
1370
1371
1372 /* A subroutine of gfc_add_interface_mapping.  Return a descriptorless
1373    array variable that can be used as the actual argument for dummy
1374    argument SYM.  Add any initialization code to BLOCK.  PACKED is as
1375    for gfc_get_nodesc_array_type and DATA points to the first element
1376    in the passed array.  */
1377
1378 static tree
1379 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
1380                                  gfc_packed packed, tree data)
1381 {
1382   tree type;
1383   tree var;
1384
1385   type = gfc_typenode_for_spec (&sym->ts);
1386   type = gfc_get_nodesc_array_type (type, sym->as, packed);
1387
1388   var = gfc_create_var (type, "ifm");
1389   gfc_add_modify_expr (block, var, fold_convert (type, data));
1390
1391   return var;
1392 }
1393
1394
1395 /* A subroutine of gfc_add_interface_mapping.  Set the stride, upper bounds
1396    and offset of descriptorless array type TYPE given that it has the same
1397    size as DESC.  Add any set-up code to BLOCK.  */
1398
1399 static void
1400 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
1401 {
1402   int n;
1403   tree dim;
1404   tree offset;
1405   tree tmp;
1406
1407   offset = gfc_index_zero_node;
1408   for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
1409     {
1410       dim = gfc_rank_cst[n];
1411       GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
1412       if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
1413         {
1414           GFC_TYPE_ARRAY_LBOUND (type, n)
1415                 = gfc_conv_descriptor_lbound (desc, dim);
1416           GFC_TYPE_ARRAY_UBOUND (type, n)
1417                 = gfc_conv_descriptor_ubound (desc, dim);
1418         }
1419       else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
1420         {
1421           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1422                              gfc_conv_descriptor_ubound (desc, dim),
1423                              gfc_conv_descriptor_lbound (desc, dim));
1424           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1425                              GFC_TYPE_ARRAY_LBOUND (type, n),
1426                              tmp);
1427           tmp = gfc_evaluate_now (tmp, block);
1428           GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
1429         }
1430       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
1431                          GFC_TYPE_ARRAY_LBOUND (type, n),
1432                          GFC_TYPE_ARRAY_STRIDE (type, n));
1433       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
1434     }
1435   offset = gfc_evaluate_now (offset, block);
1436   GFC_TYPE_ARRAY_OFFSET (type) = offset;
1437 }
1438
1439
1440 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
1441    in SE.  The caller may still use se->expr and se->string_length after
1442    calling this function.  */
1443
1444 void
1445 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
1446                            gfc_symbol * sym, gfc_se * se)
1447 {
1448   gfc_interface_sym_mapping *sm;
1449   tree desc;
1450   tree tmp;
1451   tree value;
1452   gfc_symbol *new_sym;
1453   gfc_symtree *root;
1454   gfc_symtree *new_symtree;
1455
1456   /* Create a new symbol to represent the actual argument.  */
1457   new_sym = gfc_new_symbol (sym->name, NULL);
1458   new_sym->ts = sym->ts;
1459   new_sym->attr.referenced = 1;
1460   new_sym->attr.dimension = sym->attr.dimension;
1461   new_sym->attr.pointer = sym->attr.pointer;
1462   new_sym->attr.allocatable = sym->attr.allocatable;
1463   new_sym->attr.flavor = sym->attr.flavor;
1464
1465   /* Create a fake symtree for it.  */
1466   root = NULL;
1467   new_symtree = gfc_new_symtree (&root, sym->name);
1468   new_symtree->n.sym = new_sym;
1469   gcc_assert (new_symtree == root);
1470
1471   /* Create a dummy->actual mapping.  */
1472   sm = gfc_getmem (sizeof (*sm));
1473   sm->next = mapping->syms;
1474   sm->old = sym;
1475   sm->new = new_symtree;
1476   mapping->syms = sm;
1477
1478   /* Stabilize the argument's value.  */
1479   se->expr = gfc_evaluate_now (se->expr, &se->pre);
1480
1481   if (sym->ts.type == BT_CHARACTER)
1482     {
1483       /* Create a copy of the dummy argument's length.  */
1484       new_sym->ts.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.cl);
1485
1486       /* If the length is specified as "*", record the length that
1487          the caller is passing.  We should use the callee's length
1488          in all other cases.  */
1489       if (!new_sym->ts.cl->length)
1490         {
1491           se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
1492           new_sym->ts.cl->backend_decl = se->string_length;
1493         }
1494     }
1495
1496   /* Use the passed value as-is if the argument is a function.  */
1497   if (sym->attr.flavor == FL_PROCEDURE)
1498     value = se->expr;
1499
1500   /* If the argument is either a string or a pointer to a string,
1501      convert it to a boundless character type.  */
1502   else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
1503     {
1504       tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
1505       tmp = build_pointer_type (tmp);
1506       if (sym->attr.pointer)
1507         value = build_fold_indirect_ref (se->expr);
1508       else
1509         value = se->expr;
1510       value = fold_convert (tmp, value);
1511     }
1512
1513   /* If the argument is a scalar, a pointer to an array or an allocatable,
1514      dereference it.  */
1515   else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
1516     value = build_fold_indirect_ref (se->expr);
1517   
1518   /* For character(*), use the actual argument's descriptor.  */  
1519   else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.cl->length)
1520     value = build_fold_indirect_ref (se->expr);
1521
1522   /* If the argument is an array descriptor, use it to determine
1523      information about the actual argument's shape.  */
1524   else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
1525            && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
1526     {
1527       /* Get the actual argument's descriptor.  */
1528       desc = build_fold_indirect_ref (se->expr);
1529
1530       /* Create the replacement variable.  */
1531       tmp = gfc_conv_descriptor_data_get (desc);
1532       value = gfc_get_interface_mapping_array (&se->pre, sym,
1533                                                PACKED_NO, tmp);
1534
1535       /* Use DESC to work out the upper bounds, strides and offset.  */
1536       gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
1537     }
1538   else
1539     /* Otherwise we have a packed array.  */
1540     value = gfc_get_interface_mapping_array (&se->pre, sym,
1541                                              PACKED_FULL, se->expr);
1542
1543   new_sym->backend_decl = value;
1544 }
1545
1546
1547 /* Called once all dummy argument mappings have been added to MAPPING,
1548    but before the mapping is used to evaluate expressions.  Pre-evaluate
1549    the length of each argument, adding any initialization code to PRE and
1550    any finalization code to POST.  */
1551
1552 void
1553 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
1554                               stmtblock_t * pre, stmtblock_t * post)
1555 {
1556   gfc_interface_sym_mapping *sym;
1557   gfc_expr *expr;
1558   gfc_se se;
1559
1560   for (sym = mapping->syms; sym; sym = sym->next)
1561     if (sym->new->n.sym->ts.type == BT_CHARACTER
1562         && !sym->new->n.sym->ts.cl->backend_decl)
1563       {
1564         expr = sym->new->n.sym->ts.cl->length;
1565         gfc_apply_interface_mapping_to_expr (mapping, expr);
1566         gfc_init_se (&se, NULL);
1567         gfc_conv_expr (&se, expr);
1568
1569         se.expr = gfc_evaluate_now (se.expr, &se.pre);
1570         gfc_add_block_to_block (pre, &se.pre);
1571         gfc_add_block_to_block (post, &se.post);
1572
1573         sym->new->n.sym->ts.cl->backend_decl = se.expr;
1574       }
1575 }
1576
1577
1578 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1579    constructor C.  */
1580
1581 static void
1582 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
1583                                      gfc_constructor * c)
1584 {
1585   for (; c; c = c->next)
1586     {
1587       gfc_apply_interface_mapping_to_expr (mapping, c->expr);
1588       if (c->iterator)
1589         {
1590           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
1591           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
1592           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
1593         }
1594     }
1595 }
1596
1597
1598 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1599    reference REF.  */
1600
1601 static void
1602 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
1603                                     gfc_ref * ref)
1604 {
1605   int n;
1606
1607   for (; ref; ref = ref->next)
1608     switch (ref->type)
1609       {
1610       case REF_ARRAY:
1611         for (n = 0; n < ref->u.ar.dimen; n++)
1612           {
1613             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
1614             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
1615             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
1616           }
1617         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
1618         break;
1619
1620       case REF_COMPONENT:
1621         break;
1622
1623       case REF_SUBSTRING:
1624         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
1625         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
1626         break;
1627       }
1628 }
1629
1630
1631 /* EXPR is a copy of an expression that appeared in the interface
1632    associated with MAPPING.  Walk it recursively looking for references to
1633    dummy arguments that MAPPING maps to actual arguments.  Replace each such
1634    reference with a reference to the associated actual argument.  */
1635
1636 static int
1637 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
1638                                      gfc_expr * expr)
1639 {
1640   gfc_interface_sym_mapping *sym;
1641   gfc_actual_arglist *actual;
1642   int seen_result = 0;
1643
1644   if (!expr)
1645     return 0;
1646
1647   /* Copying an expression does not copy its length, so do that here.  */
1648   if (expr->ts.type == BT_CHARACTER && expr->ts.cl)
1649     {
1650       expr->ts.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.cl);
1651       gfc_apply_interface_mapping_to_expr (mapping, expr->ts.cl->length);
1652     }
1653
1654   /* Apply the mapping to any references.  */
1655   gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
1656
1657   /* ...and to the expression's symbol, if it has one.  */
1658   if (expr->symtree)
1659     for (sym = mapping->syms; sym; sym = sym->next)
1660       if (sym->old == expr->symtree->n.sym)
1661         expr->symtree = sym->new;
1662
1663   /* ...and to subexpressions in expr->value.  */
1664   switch (expr->expr_type)
1665     {
1666     case EXPR_VARIABLE:
1667       if (expr->symtree->n.sym->attr.result)
1668         seen_result = 1;
1669     case EXPR_CONSTANT:
1670     case EXPR_NULL:
1671     case EXPR_SUBSTRING:
1672       break;
1673
1674     case EXPR_OP:
1675       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
1676       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
1677       break;
1678
1679     case EXPR_FUNCTION:
1680       if (expr->value.function.esym == NULL
1681             && expr->value.function.isym != NULL
1682             && expr->value.function.isym->id == GFC_ISYM_LEN
1683             && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE
1684             && gfc_apply_interface_mapping_to_expr (mapping,
1685                         expr->value.function.actual->expr))
1686         {
1687           gfc_expr *new_expr;
1688           new_expr = gfc_copy_expr (expr->value.function.actual->expr->ts.cl->length);
1689           *expr = *new_expr;
1690           gfc_free (new_expr);
1691           gfc_apply_interface_mapping_to_expr (mapping, expr);
1692           break;
1693         }
1694
1695       for (sym = mapping->syms; sym; sym = sym->next)
1696         if (sym->old == expr->value.function.esym)
1697           expr->value.function.esym = sym->new->n.sym;
1698
1699       for (actual = expr->value.function.actual; actual; actual = actual->next)
1700         gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
1701       break;
1702
1703     case EXPR_ARRAY:
1704     case EXPR_STRUCTURE:
1705       gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
1706       break;
1707     }
1708   return seen_result;
1709 }
1710
1711
1712 /* Evaluate interface expression EXPR using MAPPING.  Store the result
1713    in SE.  */
1714
1715 void
1716 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
1717                              gfc_se * se, gfc_expr * expr)
1718 {
1719   expr = gfc_copy_expr (expr);
1720   gfc_apply_interface_mapping_to_expr (mapping, expr);
1721   gfc_conv_expr (se, expr);
1722   se->expr = gfc_evaluate_now (se->expr, &se->pre);
1723   gfc_free_expr (expr);
1724 }
1725
1726 /* Returns a reference to a temporary array into which a component of
1727    an actual argument derived type array is copied and then returned
1728    after the function call.
1729    TODO Get rid of this kludge, when array descriptors are capable of
1730    handling arrays with a bigger stride in bytes than size.  */
1731
1732 void
1733 gfc_conv_aliased_arg (gfc_se * parmse, gfc_expr * expr,
1734                       int g77, sym_intent intent)
1735 {
1736   gfc_se lse;
1737   gfc_se rse;
1738   gfc_ss *lss;
1739   gfc_ss *rss;
1740   gfc_loopinfo loop;
1741   gfc_loopinfo loop2;
1742   gfc_ss_info *info;
1743   tree offset;
1744   tree tmp_index;
1745   tree tmp;
1746   tree base_type;
1747   stmtblock_t body;
1748   int n;
1749
1750   gcc_assert (expr->expr_type == EXPR_VARIABLE);
1751
1752   gfc_init_se (&lse, NULL);
1753   gfc_init_se (&rse, NULL);
1754
1755   /* Walk the argument expression.  */
1756   rss = gfc_walk_expr (expr);
1757
1758   gcc_assert (rss != gfc_ss_terminator);
1759  
1760   /* Initialize the scalarizer.  */
1761   gfc_init_loopinfo (&loop);
1762   gfc_add_ss_to_loop (&loop, rss);
1763
1764   /* Calculate the bounds of the scalarization.  */
1765   gfc_conv_ss_startstride (&loop);
1766
1767   /* Build an ss for the temporary.  */
1768   base_type = gfc_typenode_for_spec (&expr->ts);
1769   if (GFC_ARRAY_TYPE_P (base_type)
1770                 || GFC_DESCRIPTOR_TYPE_P (base_type))
1771     base_type = gfc_get_element_type (base_type);
1772
1773   loop.temp_ss = gfc_get_ss ();;
1774   loop.temp_ss->type = GFC_SS_TEMP;
1775   loop.temp_ss->data.temp.type = base_type;
1776
1777   if (expr->ts.type == BT_CHARACTER)
1778     {
1779       gfc_ref *char_ref = expr->ref;
1780
1781       for (; char_ref; char_ref = char_ref->next)
1782         if (char_ref->type == REF_SUBSTRING)
1783           {
1784             gfc_se tmp_se;
1785
1786             expr->ts.cl = gfc_get_charlen ();
1787             expr->ts.cl->next = char_ref->u.ss.length->next;
1788             char_ref->u.ss.length->next = expr->ts.cl;
1789
1790             gfc_init_se (&tmp_se, NULL);
1791             gfc_conv_expr_type (&tmp_se, char_ref->u.ss.end,
1792                                 gfc_array_index_type);
1793             tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1794                                tmp_se.expr, gfc_index_one_node);
1795             tmp = gfc_evaluate_now (tmp, &parmse->pre);
1796             gfc_init_se (&tmp_se, NULL);
1797             gfc_conv_expr_type (&tmp_se, char_ref->u.ss.start,
1798                                 gfc_array_index_type);
1799             tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1800                                tmp, tmp_se.expr);
1801             expr->ts.cl->backend_decl = tmp;
1802
1803             break;
1804           }
1805       loop.temp_ss->data.temp.type
1806                 = gfc_typenode_for_spec (&expr->ts);
1807       loop.temp_ss->string_length = expr->ts.cl->backend_decl;
1808     }
1809
1810   loop.temp_ss->data.temp.dimen = loop.dimen;
1811   loop.temp_ss->next = gfc_ss_terminator;
1812
1813   /* Associate the SS with the loop.  */
1814   gfc_add_ss_to_loop (&loop, loop.temp_ss);
1815
1816   /* Setup the scalarizing loops.  */
1817   gfc_conv_loop_setup (&loop);
1818
1819   /* Pass the temporary descriptor back to the caller.  */
1820   info = &loop.temp_ss->data.info;
1821   parmse->expr = info->descriptor;
1822
1823   /* Setup the gfc_se structures.  */
1824   gfc_copy_loopinfo_to_se (&lse, &loop);
1825   gfc_copy_loopinfo_to_se (&rse, &loop);
1826
1827   rse.ss = rss;
1828   lse.ss = loop.temp_ss;
1829   gfc_mark_ss_chain_used (rss, 1);
1830   gfc_mark_ss_chain_used (loop.temp_ss, 1);
1831
1832   /* Start the scalarized loop body.  */
1833   gfc_start_scalarized_body (&loop, &body);
1834
1835   /* Translate the expression.  */
1836   gfc_conv_expr (&rse, expr);
1837
1838   gfc_conv_tmp_array_ref (&lse);
1839   gfc_advance_se_ss_chain (&lse);
1840
1841   if (intent != INTENT_OUT)
1842     {
1843       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false);
1844       gfc_add_expr_to_block (&body, tmp);
1845       gcc_assert (rse.ss == gfc_ss_terminator);
1846       gfc_trans_scalarizing_loops (&loop, &body);
1847     }
1848   else
1849     {
1850       /* Make sure that the temporary declaration survives by merging
1851        all the loop declarations into the current context.  */
1852       for (n = 0; n < loop.dimen; n++)
1853         {
1854           gfc_merge_block_scope (&body);
1855           body = loop.code[loop.order[n]];
1856         }
1857       gfc_merge_block_scope (&body);
1858     }
1859
1860   /* Add the post block after the second loop, so that any
1861      freeing of allocated memory is done at the right time.  */
1862   gfc_add_block_to_block (&parmse->pre, &loop.pre);
1863
1864   /**********Copy the temporary back again.*********/
1865
1866   gfc_init_se (&lse, NULL);
1867   gfc_init_se (&rse, NULL);
1868
1869   /* Walk the argument expression.  */
1870   lss = gfc_walk_expr (expr);
1871   rse.ss = loop.temp_ss;
1872   lse.ss = lss;
1873
1874   /* Initialize the scalarizer.  */
1875   gfc_init_loopinfo (&loop2);
1876   gfc_add_ss_to_loop (&loop2, lss);
1877
1878   /* Calculate the bounds of the scalarization.  */
1879   gfc_conv_ss_startstride (&loop2);
1880
1881   /* Setup the scalarizing loops.  */
1882   gfc_conv_loop_setup (&loop2);
1883
1884   gfc_copy_loopinfo_to_se (&lse, &loop2);
1885   gfc_copy_loopinfo_to_se (&rse, &loop2);
1886
1887   gfc_mark_ss_chain_used (lss, 1);
1888   gfc_mark_ss_chain_used (loop.temp_ss, 1);
1889
1890   /* Declare the variable to hold the temporary offset and start the
1891      scalarized loop body.  */
1892   offset = gfc_create_var (gfc_array_index_type, NULL);
1893   gfc_start_scalarized_body (&loop2, &body);
1894
1895   /* Build the offsets for the temporary from the loop variables.  The
1896      temporary array has lbounds of zero and strides of one in all
1897      dimensions, so this is very simple.  The offset is only computed
1898      outside the innermost loop, so the overall transfer could be
1899      optimized further.  */
1900   info = &rse.ss->data.info;
1901
1902   tmp_index = gfc_index_zero_node;
1903   for (n = info->dimen - 1; n > 0; n--)
1904     {
1905       tree tmp_str;
1906       tmp = rse.loop->loopvar[n];
1907       tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1908                          tmp, rse.loop->from[n]);
1909       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1910                          tmp, tmp_index);
1911
1912       tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1913                              rse.loop->to[n-1], rse.loop->from[n-1]);
1914       tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1915                              tmp_str, gfc_index_one_node);
1916
1917       tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
1918                                tmp, tmp_str);
1919     }
1920
1921   tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1922                            tmp_index, rse.loop->from[0]);
1923   gfc_add_modify_expr (&rse.loop->code[0], offset, tmp_index);
1924
1925   tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1926                            rse.loop->loopvar[0], offset);
1927
1928   /* Now use the offset for the reference.  */
1929   tmp = build_fold_indirect_ref (info->data);
1930   rse.expr = gfc_build_array_ref (tmp, tmp_index);
1931
1932   if (expr->ts.type == BT_CHARACTER)
1933     rse.string_length = expr->ts.cl->backend_decl;
1934
1935   gfc_conv_expr (&lse, expr);
1936
1937   gcc_assert (lse.ss == gfc_ss_terminator);
1938
1939   tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
1940   gfc_add_expr_to_block (&body, tmp);
1941   
1942   /* Generate the copying loops.  */
1943   gfc_trans_scalarizing_loops (&loop2, &body);
1944
1945   /* Wrap the whole thing up by adding the second loop to the post-block
1946      and following it by the post-block of the first loop.  In this way,
1947      if the temporary needs freeing, it is done after use!  */
1948   if (intent != INTENT_IN)
1949     {
1950       gfc_add_block_to_block (&parmse->post, &loop2.pre);
1951       gfc_add_block_to_block (&parmse->post, &loop2.post);
1952     }
1953
1954   gfc_add_block_to_block (&parmse->post, &loop.post);
1955
1956   gfc_cleanup_loop (&loop);
1957   gfc_cleanup_loop (&loop2);
1958
1959   /* Pass the string length to the argument expression.  */
1960   if (expr->ts.type == BT_CHARACTER)
1961     parmse->string_length = expr->ts.cl->backend_decl;
1962
1963   /* We want either the address for the data or the address of the descriptor,
1964      depending on the mode of passing array arguments.  */
1965   if (g77)
1966     parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
1967   else
1968     parmse->expr = build_fold_addr_expr (parmse->expr);
1969
1970   return;
1971 }
1972
1973 /* Is true if an array reference is followed by a component or substring
1974    reference.  */
1975
1976 bool
1977 is_aliased_array (gfc_expr * e)
1978 {
1979   gfc_ref * ref;
1980   bool seen_array;
1981
1982   seen_array = false;   
1983   for (ref = e->ref; ref; ref = ref->next)
1984     {
1985       if (ref->type == REF_ARRAY
1986             && ref->u.ar.type != AR_ELEMENT)
1987         seen_array = true;
1988
1989       if (seen_array
1990             && ref->type != REF_ARRAY)
1991         return seen_array;
1992     }
1993   return false;
1994 }
1995
1996 /* Generate the code for argument list functions.  */
1997
1998 static void
1999 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
2000 {
2001   /* Pass by value for g77 %VAL(arg), pass the address
2002      indirectly for %LOC, else by reference.  Thus %REF
2003      is a "do-nothing" and %LOC is the same as an F95
2004      pointer.  */
2005   if (strncmp (name, "%VAL", 4) == 0)
2006     gfc_conv_expr (se, expr);
2007   else if (strncmp (name, "%LOC", 4) == 0)
2008     {
2009       gfc_conv_expr_reference (se, expr);
2010       se->expr = gfc_build_addr_expr (NULL, se->expr);
2011     }
2012   else if (strncmp (name, "%REF", 4) == 0)
2013     gfc_conv_expr_reference (se, expr);
2014   else
2015     gfc_error ("Unknown argument list function at %L", &expr->where);
2016 }
2017
2018
2019 /* Generate code for a procedure call.  Note can return se->post != NULL.
2020    If se->direct_byref is set then se->expr contains the return parameter.
2021    Return nonzero, if the call has alternate specifiers.  */
2022
2023 int
2024 gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
2025                         gfc_actual_arglist * arg, tree append_args)
2026 {
2027   gfc_interface_mapping mapping;
2028   tree arglist;
2029   tree retargs;
2030   tree tmp;
2031   tree fntype;
2032   gfc_se parmse;
2033   gfc_ss *argss;
2034   gfc_ss_info *info;
2035   int byref;
2036   int parm_kind;
2037   tree type;
2038   tree var;
2039   tree len;
2040   tree stringargs;
2041   gfc_formal_arglist *formal;
2042   int has_alternate_specifier = 0;
2043   bool need_interface_mapping;
2044   bool callee_alloc;
2045   gfc_typespec ts;
2046   gfc_charlen cl;
2047   gfc_expr *e;
2048   gfc_symbol *fsym;
2049   stmtblock_t post;
2050   enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
2051
2052   arglist = NULL_TREE;
2053   retargs = NULL_TREE;
2054   stringargs = NULL_TREE;
2055   var = NULL_TREE;
2056   len = NULL_TREE;
2057
2058   if (sym->from_intmod == INTMOD_ISO_C_BINDING)
2059     {
2060       if (sym->intmod_sym_id == ISOCBINDING_LOC)
2061         {
2062           if (arg->expr->rank == 0)
2063             gfc_conv_expr_reference (se, arg->expr);
2064           else
2065             {
2066               int f;
2067               /* This is really the actual arg because no formal arglist is
2068                  created for C_LOC.      */
2069               fsym = arg->expr->symtree->n.sym;
2070
2071               /* We should want it to do g77 calling convention.  */
2072               f = (fsym != NULL)
2073                 && !(fsym->attr.pointer || fsym->attr.allocatable)
2074                 && fsym->as->type != AS_ASSUMED_SHAPE;
2075               f = f || !sym->attr.always_explicit;
2076           
2077               argss = gfc_walk_expr (arg->expr);
2078               gfc_conv_array_parameter (se, arg->expr, argss, f);
2079             }
2080
2081           return 0;
2082         }
2083       else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
2084         {
2085           arg->expr->ts.type = sym->ts.derived->ts.type;
2086           arg->expr->ts.f90_type = sym->ts.derived->ts.f90_type;
2087           arg->expr->ts.kind = sym->ts.derived->ts.kind;
2088           gfc_conv_expr_reference (se, arg->expr);
2089       
2090           return 0;
2091         }
2092     }
2093   
2094   if (se->ss != NULL)
2095     {
2096       if (!sym->attr.elemental)
2097         {
2098           gcc_assert (se->ss->type == GFC_SS_FUNCTION);
2099           if (se->ss->useflags)
2100             {
2101               gcc_assert (gfc_return_by_reference (sym)
2102                       && sym->result->attr.dimension);
2103               gcc_assert (se->loop != NULL);
2104
2105               /* Access the previously obtained result.  */
2106               gfc_conv_tmp_array_ref (se);
2107               gfc_advance_se_ss_chain (se);
2108               return 0;
2109             }
2110         }
2111       info = &se->ss->data.info;
2112     }
2113   else
2114     info = NULL;
2115
2116   gfc_init_block (&post);
2117   gfc_init_interface_mapping (&mapping);
2118   need_interface_mapping = ((sym->ts.type == BT_CHARACTER
2119                                   && sym->ts.cl->length
2120                                   && sym->ts.cl->length->expr_type
2121                                                 != EXPR_CONSTANT)
2122                               || sym->attr.dimension);
2123   formal = sym->formal;
2124   /* Evaluate the arguments.  */
2125   for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
2126     {
2127       e = arg->expr;
2128       fsym = formal ? formal->sym : NULL;
2129       parm_kind = MISSING;
2130       if (e == NULL)
2131         {
2132
2133           if (se->ignore_optional)
2134             {
2135               /* Some intrinsics have already been resolved to the correct
2136                  parameters.  */
2137               continue;
2138             }
2139           else if (arg->label)
2140             {
2141               has_alternate_specifier = 1;
2142               continue;
2143             }
2144           else
2145             {
2146               /* Pass a NULL pointer for an absent arg.  */
2147               gfc_init_se (&parmse, NULL);
2148               parmse.expr = null_pointer_node;
2149               if (arg->missing_arg_type == BT_CHARACTER)
2150                 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
2151             }
2152         }
2153       else if (se->ss && se->ss->useflags)
2154         {
2155           /* An elemental function inside a scalarized loop.  */
2156           gfc_init_se (&parmse, se);
2157           gfc_conv_expr_reference (&parmse, e);
2158           parm_kind = ELEMENTAL;
2159         }
2160       else
2161         {
2162           /* A scalar or transformational function.  */
2163           gfc_init_se (&parmse, NULL);
2164           argss = gfc_walk_expr (e);
2165
2166           if (argss == gfc_ss_terminator)
2167             {
2168               if (fsym && fsym->attr.value)
2169                 {
2170                   gfc_conv_expr (&parmse, e);
2171                 }
2172               else if (arg->name && arg->name[0] == '%')
2173                 /* Argument list functions %VAL, %LOC and %REF are signalled
2174                    through arg->name.  */
2175                 conv_arglist_function (&parmse, arg->expr, arg->name);
2176               else if ((e->expr_type == EXPR_FUNCTION)
2177                           && e->symtree->n.sym->attr.pointer
2178                           && fsym && fsym->attr.target)
2179                 {
2180                   gfc_conv_expr (&parmse, e);
2181                   parmse.expr = build_fold_addr_expr (parmse.expr);
2182                 }
2183               else
2184                 {
2185                   gfc_conv_expr_reference (&parmse, e);
2186                   if (fsym && fsym->attr.pointer
2187                       && fsym->attr.flavor != FL_PROCEDURE
2188                       && e->expr_type != EXPR_NULL)
2189                     {
2190                       /* Scalar pointer dummy args require an extra level of
2191                          indirection. The null pointer already contains
2192                          this level of indirection.  */
2193                       parm_kind = SCALAR_POINTER;
2194                       parmse.expr = build_fold_addr_expr (parmse.expr);
2195                     }
2196                 }
2197             }
2198           else
2199             {
2200               /* If the procedure requires an explicit interface, the actual
2201                  argument is passed according to the corresponding formal
2202                  argument.  If the corresponding formal argument is a POINTER,
2203                  ALLOCATABLE or assumed shape, we do not use g77's calling
2204                  convention, and pass the address of the array descriptor
2205                  instead. Otherwise we use g77's calling convention.  */
2206               int f;
2207               f = (fsym != NULL)
2208                   && !(fsym->attr.pointer || fsym->attr.allocatable)
2209                   && fsym->as->type != AS_ASSUMED_SHAPE;
2210               f = f || !sym->attr.always_explicit;
2211
2212               if (e->expr_type == EXPR_VARIABLE
2213                     && is_aliased_array (e))
2214                 /* The actual argument is a component reference to an
2215                    array of derived types.  In this case, the argument
2216                    is converted to a temporary, which is passed and then
2217                    written back after the procedure call.  */
2218                 gfc_conv_aliased_arg (&parmse, e, f,
2219                         fsym ? fsym->attr.intent : INTENT_INOUT);
2220               else
2221                 gfc_conv_array_parameter (&parmse, e, argss, f);
2222
2223               /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 
2224                  allocated on entry, it must be deallocated.  */
2225               if (fsym && fsym->attr.allocatable
2226                   && fsym->attr.intent == INTENT_OUT)
2227                 {
2228                   tmp = build_fold_indirect_ref (parmse.expr);
2229                   tmp = gfc_trans_dealloc_allocated (tmp);
2230                   gfc_add_expr_to_block (&se->pre, tmp);
2231                 }
2232
2233             } 
2234         }
2235
2236       if (fsym)
2237         {
2238           if (e)
2239             {
2240               /* If an optional argument is itself an optional dummy
2241                  argument, check its presence and substitute a null
2242                  if absent.  */
2243               if (e->expr_type == EXPR_VARIABLE
2244                     && e->symtree->n.sym->attr.optional
2245                     && fsym->attr.optional)
2246                 gfc_conv_missing_dummy (&parmse, e, fsym->ts);
2247
2248               /* If an INTENT(OUT) dummy of derived type has a default
2249                  initializer, it must be (re)initialized here.  */
2250               if (fsym->attr.intent == INTENT_OUT
2251                     && fsym->ts.type == BT_DERIVED
2252                     && fsym->value)
2253                 {
2254                   gcc_assert (!fsym->attr.allocatable);
2255                   tmp = gfc_trans_assignment (e, fsym->value, false);
2256                   gfc_add_expr_to_block (&se->pre, tmp);
2257                 }
2258
2259               /* Obtain the character length of an assumed character
2260                  length procedure from the typespec.  */
2261               if (fsym->ts.type == BT_CHARACTER
2262                     && parmse.string_length == NULL_TREE
2263                     && e->ts.type == BT_PROCEDURE
2264                     && e->symtree->n.sym->ts.type == BT_CHARACTER
2265                     && e->symtree->n.sym->ts.cl->length != NULL)
2266                 {
2267                   gfc_conv_const_charlen (e->symtree->n.sym->ts.cl);
2268                   parmse.string_length
2269                         = e->symtree->n.sym->ts.cl->backend_decl;
2270                 }
2271             }
2272
2273           if (need_interface_mapping)
2274             gfc_add_interface_mapping (&mapping, fsym, &parmse);
2275         }
2276
2277       gfc_add_block_to_block (&se->pre, &parmse.pre);
2278       gfc_add_block_to_block (&post, &parmse.post);
2279
2280       /* Allocated allocatable components of derived types must be
2281          deallocated for INTENT(OUT) dummy arguments and non-variable
2282          scalars.  Non-variable arrays are dealt with in trans-array.c
2283          (gfc_conv_array_parameter).  */
2284       if (e && e->ts.type == BT_DERIVED
2285             && e->ts.derived->attr.alloc_comp
2286             && ((formal && formal->sym->attr.intent == INTENT_OUT)
2287                    ||
2288                 (e->expr_type != EXPR_VARIABLE && !e->rank)))
2289         {
2290           int parm_rank;
2291           tmp = build_fold_indirect_ref (parmse.expr);
2292           parm_rank = e->rank;
2293           switch (parm_kind)
2294             {
2295             case (ELEMENTAL):
2296             case (SCALAR):
2297               parm_rank = 0;
2298               break;
2299
2300             case (SCALAR_POINTER):
2301               tmp = build_fold_indirect_ref (tmp);
2302               break;
2303             case (ARRAY):
2304               tmp = parmse.expr;
2305               break;
2306             }
2307
2308           tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
2309           if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional)
2310             tmp = build3_v (COND_EXPR, gfc_conv_expr_present (e->symtree->n.sym),
2311                             tmp, build_empty_stmt ());
2312
2313           if (e->expr_type != EXPR_VARIABLE)
2314             /* Don't deallocate non-variables until they have been used.  */
2315             gfc_add_expr_to_block (&se->post, tmp);
2316           else 
2317             {
2318               gcc_assert (formal && formal->sym->attr.intent == INTENT_OUT);
2319               gfc_add_expr_to_block (&se->pre, tmp);
2320             }
2321         }
2322
2323       /* Character strings are passed as two parameters, a length and a
2324          pointer.  */
2325       if (parmse.string_length != NULL_TREE)
2326         stringargs = gfc_chainon_list (stringargs, parmse.string_length);
2327
2328       arglist = gfc_chainon_list (arglist, parmse.expr);
2329     }
2330   gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
2331
2332   ts = sym->ts;
2333   if (ts.type == BT_CHARACTER)
2334     {
2335       if (sym->ts.cl->length == NULL)
2336         {
2337           /* Assumed character length results are not allowed by 5.1.1.5 of the
2338              standard and are trapped in resolve.c; except in the case of SPREAD
2339              (and other intrinsics?) and dummy functions.  In the case of SPREAD,
2340              we take the character length of the first argument for the result.
2341              For dummies, we have to look through the formal argument list for
2342              this function and use the character length found there.*/
2343           if (!sym->attr.dummy)
2344             cl.backend_decl = TREE_VALUE (stringargs);
2345           else
2346             {
2347               formal = sym->ns->proc_name->formal;
2348               for (; formal; formal = formal->next)
2349                 if (strcmp (formal->sym->name, sym->name) == 0)
2350                   cl.backend_decl = formal->sym->ts.cl->backend_decl;
2351             }
2352         }
2353         else
2354         {
2355           tree tmp;
2356
2357           /* Calculate the length of the returned string.  */
2358           gfc_init_se (&parmse, NULL);
2359           if (need_interface_mapping)
2360             gfc_apply_interface_mapping (&mapping, &parmse, sym->ts.cl->length);
2361           else
2362             gfc_conv_expr (&parmse, sym->ts.cl->length);
2363           gfc_add_block_to_block (&se->pre, &parmse.pre);
2364           gfc_add_block_to_block (&se->post, &parmse.post);
2365           
2366           tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
2367           tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
2368                              build_int_cst (gfc_charlen_type_node, 0));
2369           cl.backend_decl = tmp;
2370         }
2371
2372       /* Set up a charlen structure for it.  */
2373       cl.next = NULL;
2374       cl.length = NULL;
2375       ts.cl = &cl;
2376
2377       len = cl.backend_decl;
2378     }
2379
2380   byref = gfc_return_by_reference (sym);
2381   if (byref)
2382     {
2383       if (se->direct_byref)
2384         {
2385           /* Sometimes, too much indirection can be applied; eg. for
2386              function_result = array_valued_recursive_function.  */
2387           if (TREE_TYPE (TREE_TYPE (se->expr))
2388                 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
2389                 && GFC_DESCRIPTOR_TYPE_P
2390                         (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
2391             se->expr = build_fold_indirect_ref (se->expr);
2392
2393           retargs = gfc_chainon_list (retargs, se->expr);
2394         }
2395       else if (sym->result->attr.dimension)
2396         {
2397           gcc_assert (se->loop && info);
2398
2399           /* Set the type of the array.  */
2400           tmp = gfc_typenode_for_spec (&ts);
2401           info->dimen = se->loop->dimen;
2402
2403           /* Evaluate the bounds of the result, if known.  */
2404           gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
2405
2406           /* Create a temporary to store the result.  In case the function
2407              returns a pointer, the temporary will be a shallow copy and
2408              mustn't be deallocated.  */
2409           callee_alloc = sym->attr.allocatable || sym->attr.pointer;
2410           gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
2411                                        false, !sym->attr.pointer, callee_alloc);
2412
2413           /* Pass the temporary as the first argument.  */
2414           tmp = info->descriptor;
2415           tmp = build_fold_addr_expr (tmp);
2416           retargs = gfc_chainon_list (retargs, tmp);
2417         }
2418       else if (ts.type == BT_CHARACTER)
2419         {
2420           /* Pass the string length.  */
2421           type = gfc_get_character_type (ts.kind, ts.cl);
2422           type = build_pointer_type (type);
2423
2424           /* Return an address to a char[0:len-1]* temporary for
2425              character pointers.  */
2426           if (sym->attr.pointer || sym->attr.allocatable)
2427             {
2428               /* Build char[0:len-1] * pstr.  */
2429               tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
2430                                  build_int_cst (gfc_charlen_type_node, 1));
2431               tmp = build_range_type (gfc_array_index_type,
2432                                       gfc_index_zero_node, tmp);
2433               tmp = build_array_type (gfc_character1_type_node, tmp);
2434               var = gfc_create_var (build_pointer_type (tmp), "pstr");
2435
2436               /* Provide an address expression for the function arguments.  */
2437               var = build_fold_addr_expr (var);
2438             }
2439           else
2440             var = gfc_conv_string_tmp (se, type, len);
2441
2442           retargs = gfc_chainon_list (retargs, var);
2443         }
2444       else
2445         {
2446           gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
2447
2448           type = gfc_get_complex_type (ts.kind);
2449           var = build_fold_addr_expr (gfc_create_var (type, "cmplx"));
2450           retargs = gfc_chainon_list (retargs, var);
2451         }
2452
2453       /* Add the string length to the argument list.  */
2454       if (ts.type == BT_CHARACTER)
2455         retargs = gfc_chainon_list (retargs, len);
2456     }
2457   gfc_free_interface_mapping (&mapping);
2458
2459   /* Add the return arguments.  */
2460   arglist = chainon (retargs, arglist);
2461
2462   /* Add the hidden string length parameters to the arguments.  */
2463   arglist = chainon (arglist, stringargs);
2464
2465   /* We may want to append extra arguments here.  This is used e.g. for
2466      calls to libgfortran_matmul_??, which need extra information.  */
2467   if (append_args != NULL_TREE)
2468     arglist = chainon (arglist, append_args);
2469
2470   /* Generate the actual call.  */
2471   gfc_conv_function_val (se, sym);
2472
2473   /* If there are alternate return labels, function type should be
2474      integer.  Can't modify the type in place though, since it can be shared
2475      with other functions.  For dummy arguments, the typing is done to
2476      to this result, even if it has to be repeated for each call.  */
2477   if (has_alternate_specifier
2478       && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
2479     {
2480       if (!sym->attr.dummy)
2481         {
2482           TREE_TYPE (sym->backend_decl)
2483                 = build_function_type (integer_type_node,
2484                       TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
2485           se->expr = build_fold_addr_expr (sym->backend_decl);
2486         }
2487       else
2488         TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
2489     }
2490
2491   fntype = TREE_TYPE (TREE_TYPE (se->expr));
2492   se->expr = build_call_list (TREE_TYPE (fntype), se->expr, arglist);
2493
2494   /* If we have a pointer function, but we don't want a pointer, e.g.
2495      something like
2496         x = f()
2497      where f is pointer valued, we have to dereference the result.  */
2498   if (!se->want_pointer && !byref && sym->attr.pointer)
2499     se->expr = build_fold_indirect_ref (se->expr);
2500
2501   /* f2c calling conventions require a scalar default real function to
2502      return a double precision result.  Convert this back to default
2503      real.  We only care about the cases that can happen in Fortran 77.
2504   */
2505   if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
2506       && sym->ts.kind == gfc_default_real_kind
2507       && !sym->attr.always_explicit)
2508     se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
2509
2510   /* A pure function may still have side-effects - it may modify its
2511      parameters.  */
2512   TREE_SIDE_EFFECTS (se->expr) = 1;
2513 #if 0
2514   if (!sym->attr.pure)
2515     TREE_SIDE_EFFECTS (se->expr) = 1;
2516 #endif
2517
2518   if (byref)
2519     {
2520       /* Add the function call to the pre chain.  There is no expression.  */
2521       gfc_add_expr_to_block (&se->pre, se->expr);
2522       se->expr = NULL_TREE;
2523
2524       if (!se->direct_byref)
2525         {
2526           if (sym->attr.dimension)
2527             {
2528               if (flag_bounds_check)
2529                 {
2530                   /* Check the data pointer hasn't been modified.  This would
2531                      happen in a function returning a pointer.  */
2532                   tmp = gfc_conv_descriptor_data_get (info->descriptor);
2533                   tmp = fold_build2 (NE_EXPR, boolean_type_node,
2534                                      tmp, info->data);
2535                   gfc_trans_runtime_check (tmp, gfc_msg_fault, &se->pre, NULL);
2536                 }
2537               se->expr = info->descriptor;
2538               /* Bundle in the string length.  */
2539               se->string_length = len;
2540             }
2541           else if (sym->ts.type == BT_CHARACTER)
2542             {
2543               /* Dereference for character pointer results.  */
2544               if (sym->attr.pointer || sym->attr.allocatable)
2545                 se->expr = build_fold_indirect_ref (var);
2546               else
2547                 se->expr = var;
2548
2549               se->string_length = len;
2550             }
2551           else
2552             {
2553               gcc_assert (sym->ts.type == BT_COMPLEX && gfc_option.flag_f2c);
2554               se->expr = build_fold_indirect_ref (var);
2555             }
2556         }
2557     }
2558
2559   /* Follow the function call with the argument post block.  */
2560   if (byref)
2561     gfc_add_block_to_block (&se->pre, &post);
2562   else
2563     gfc_add_block_to_block (&se->post, &post);
2564
2565   return has_alternate_specifier;
2566 }
2567
2568
2569 /* Generate code to copy a string.  */
2570
2571 static void
2572 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
2573                        tree slength, tree src)
2574 {
2575   tree tmp, dlen, slen;
2576   tree dsc;
2577   tree ssc;
2578   tree cond;
2579   tree cond2;
2580   tree tmp2;
2581   tree tmp3;
2582   tree tmp4;
2583   stmtblock_t tempblock;
2584
2585   dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
2586   slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
2587
2588   /* Deal with single character specially.  */
2589   dsc = gfc_to_single_character (dlen, dest);
2590   ssc = gfc_to_single_character (slen, src);
2591   if (dsc != NULL_TREE && ssc != NULL_TREE)
2592     {
2593       gfc_add_modify_expr (block, dsc, ssc);
2594       return;
2595     }
2596
2597   /* Do nothing if the destination length is zero.  */
2598   cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
2599                       build_int_cst (size_type_node, 0));
2600
2601   /* The following code was previously in _gfortran_copy_string:
2602
2603        // The two strings may overlap so we use memmove.
2604        void
2605        copy_string (GFC_INTEGER_4 destlen, char * dest,
2606                     GFC_INTEGER_4 srclen, const char * src)
2607        {
2608          if (srclen >= destlen)
2609            {
2610              // This will truncate if too long.
2611              memmove (dest, src, destlen);
2612            }
2613          else
2614            {
2615              memmove (dest, src, srclen);
2616              // Pad with spaces.
2617              memset (&dest[srclen], ' ', destlen - srclen);
2618            }
2619        }
2620
2621      We're now doing it here for better optimization, but the logic
2622      is the same.  */
2623   
2624   /* Truncate string if source is too long.  */
2625   cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
2626   tmp2 = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE],
2627                           3, dest, src, dlen);
2628
2629   /* Else copy and pad with spaces.  */
2630   tmp3 = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE],
2631                           3, dest, src, slen);
2632
2633   tmp4 = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, dest,
2634                       fold_convert (sizetype, slen));
2635   tmp4 = build_call_expr (built_in_decls[BUILT_IN_MEMSET], 3,
2636                           tmp4, 
2637                           build_int_cst (gfc_get_int_type (gfc_c_int_kind),
2638                                          lang_hooks.to_target_charset (' ')),
2639                           fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
2640                                        dlen, slen));
2641
2642   gfc_init_block (&tempblock);
2643   gfc_add_expr_to_block (&tempblock, tmp3);
2644   gfc_add_expr_to_block (&tempblock, tmp4);
2645   tmp3 = gfc_finish_block (&tempblock);
2646
2647   /* The whole copy_string function is there.  */
2648   tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
2649   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
2650   gfc_add_expr_to_block (block, tmp);
2651 }
2652
2653
2654 /* Translate a statement function.
2655    The value of a statement function reference is obtained by evaluating the
2656    expression using the values of the actual arguments for the values of the
2657    corresponding dummy arguments.  */
2658
2659 static void
2660 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
2661 {
2662   gfc_symbol *sym;
2663   gfc_symbol *fsym;
2664   gfc_formal_arglist *fargs;
2665   gfc_actual_arglist *args;
2666   gfc_se lse;
2667   gfc_se rse;
2668   gfc_saved_var *saved_vars;
2669   tree *temp_vars;
2670   tree type;
2671   tree tmp;
2672   int n;
2673
2674   sym = expr->symtree->n.sym;
2675   args = expr->value.function.actual;
2676   gfc_init_se (&lse, NULL);
2677   gfc_init_se (&rse, NULL);
2678
2679   n = 0;
2680   for (fargs = sym->formal; fargs; fargs = fargs->next)
2681     n++;
2682   saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
2683   temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
2684
2685   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2686     {
2687       /* Each dummy shall be specified, explicitly or implicitly, to be
2688          scalar.  */
2689       gcc_assert (fargs->sym->attr.dimension == 0);
2690       fsym = fargs->sym;
2691
2692       /* Create a temporary to hold the value.  */
2693       type = gfc_typenode_for_spec (&fsym->ts);
2694       temp_vars[n] = gfc_create_var (type, fsym->name);
2695
2696       if (fsym->ts.type == BT_CHARACTER)
2697         {
2698           /* Copy string arguments.  */
2699           tree arglen;
2700
2701           gcc_assert (fsym->ts.cl && fsym->ts.cl->length
2702                   && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
2703
2704           arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2705           tmp = gfc_build_addr_expr (build_pointer_type (type),
2706                                      temp_vars[n]);
2707
2708           gfc_conv_expr (&rse, args->expr);
2709           gfc_conv_string_parameter (&rse);
2710           gfc_add_block_to_block (&se->pre, &lse.pre);
2711           gfc_add_block_to_block (&se->pre, &rse.pre);
2712
2713           gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
2714                                  rse.expr);
2715           gfc_add_block_to_block (&se->pre, &lse.post);
2716           gfc_add_block_to_block (&se->pre, &rse.post);
2717         }
2718       else
2719         {
2720           /* For everything else, just evaluate the expression.  */
2721           gfc_conv_expr (&lse, args->expr);
2722
2723           gfc_add_block_to_block (&se->pre, &lse.pre);
2724           gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
2725           gfc_add_block_to_block (&se->pre, &lse.post);
2726         }
2727
2728       args = args->next;
2729     }
2730
2731   /* Use the temporary variables in place of the real ones.  */
2732   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2733     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
2734
2735   gfc_conv_expr (se, sym->value);
2736
2737   if (sym->ts.type == BT_CHARACTER)
2738     {
2739       gfc_conv_const_charlen (sym->ts.cl);
2740
2741       /* Force the expression to the correct length.  */
2742       if (!INTEGER_CST_P (se->string_length)
2743           || tree_int_cst_lt (se->string_length,
2744                               sym->ts.cl->backend_decl))
2745         {
2746           type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
2747           tmp = gfc_create_var (type, sym->name);
2748           tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
2749           gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
2750                                  se->string_length, se->expr);
2751           se->expr = tmp;
2752         }
2753       se->string_length = sym->ts.cl->backend_decl;
2754     }
2755
2756   /* Restore the original variables.  */
2757   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2758     gfc_restore_sym (fargs->sym, &saved_vars[n]);
2759   gfc_free (saved_vars);
2760 }
2761
2762
2763 /* Translate a function expression.  */
2764
2765 static void
2766 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
2767 {
2768   gfc_symbol *sym;
2769
2770   if (expr->value.function.isym)
2771     {
2772       gfc_conv_intrinsic_function (se, expr);
2773       return;
2774     }
2775
2776   /* We distinguish statement functions from general functions to improve
2777      runtime performance.  */
2778   if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
2779     {
2780       gfc_conv_statement_function (se, expr);
2781       return;
2782     }
2783
2784   /* expr.value.function.esym is the resolved (specific) function symbol for
2785      most functions.  However this isn't set for dummy procedures.  */
2786   sym = expr->value.function.esym;
2787   if (!sym)
2788     sym = expr->symtree->n.sym;
2789   gfc_conv_function_call (se, sym, expr->value.function.actual, NULL_TREE);
2790 }
2791
2792
2793 static void
2794 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
2795 {
2796   gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
2797   gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
2798
2799   gfc_conv_tmp_array_ref (se);
2800   gfc_advance_se_ss_chain (se);
2801 }
2802
2803
2804 /* Build a static initializer.  EXPR is the expression for the initial value.
2805    The other parameters describe the variable of the component being 
2806    initialized. EXPR may be null.  */
2807
2808 tree
2809 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
2810                       bool array, bool pointer)
2811 {
2812   gfc_se se;
2813
2814   if (!(expr || pointer))
2815     return NULL_TREE;
2816
2817   if (expr != NULL && expr->ts.type == BT_DERIVED
2818       && expr->ts.is_iso_c && expr->ts.derived
2819       && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
2820           || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR))
2821       expr = gfc_int_expr (0);
2822   
2823   if (array)
2824     {
2825       /* Arrays need special handling.  */
2826       if (pointer)
2827         return gfc_build_null_descriptor (type);
2828       else
2829         return gfc_conv_array_initializer (type, expr);
2830     }
2831   else if (pointer)
2832     return fold_convert (type, null_pointer_node);
2833   else
2834     {
2835       switch (ts->type)
2836         {
2837         case BT_DERIVED:
2838           gfc_init_se (&se, NULL);
2839           gfc_conv_structure (&se, expr, 1);
2840           return se.expr;
2841
2842         case BT_CHARACTER:
2843           return gfc_conv_string_init (ts->cl->backend_decl,expr);
2844
2845         default:
2846           gfc_init_se (&se, NULL);
2847           gfc_conv_constant (&se, expr);
2848           return se.expr;
2849         }
2850     }
2851 }
2852   
2853 static tree
2854 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2855 {
2856   gfc_se rse;
2857   gfc_se lse;
2858   gfc_ss *rss;
2859   gfc_ss *lss;
2860   stmtblock_t body;
2861   stmtblock_t block;
2862   gfc_loopinfo loop;
2863   int n;
2864   tree tmp;
2865
2866   gfc_start_block (&block);
2867
2868   /* Initialize the scalarizer.  */
2869   gfc_init_loopinfo (&loop);
2870
2871   gfc_init_se (&lse, NULL);
2872   gfc_init_se (&rse, NULL);
2873
2874   /* Walk the rhs.  */
2875   rss = gfc_walk_expr (expr);
2876   if (rss == gfc_ss_terminator)
2877     {
2878       /* The rhs is scalar.  Add a ss for the expression.  */
2879       rss = gfc_get_ss ();
2880       rss->next = gfc_ss_terminator;
2881       rss->type = GFC_SS_SCALAR;
2882       rss->expr = expr;
2883     }
2884
2885   /* Create a SS for the destination.  */
2886   lss = gfc_get_ss ();
2887   lss->type = GFC_SS_COMPONENT;
2888   lss->expr = NULL;
2889   lss->shape = gfc_get_shape (cm->as->rank);
2890   lss->next = gfc_ss_terminator;
2891   lss->data.info.dimen = cm->as->rank;
2892   lss->data.info.descriptor = dest;
2893   lss->data.info.data = gfc_conv_array_data (dest);
2894   lss->data.info.offset = gfc_conv_array_offset (dest);
2895   for (n = 0; n < cm->as->rank; n++)
2896     {
2897       lss->data.info.dim[n] = n;
2898       lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
2899       lss->data.info.stride[n] = gfc_index_one_node;
2900
2901       mpz_init (lss->shape[n]);
2902       mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
2903                cm->as->lower[n]->value.integer);
2904       mpz_add_ui (lss->shape[n], lss->shape[n], 1);
2905     }
2906   
2907   /* Associate the SS with the loop.  */
2908   gfc_add_ss_to_loop (&loop, lss);
2909   gfc_add_ss_to_loop (&loop, rss);
2910
2911   /* Calculate the bounds of the scalarization.  */
2912   gfc_conv_ss_startstride (&loop);
2913
2914   /* Setup the scalarizing loops.  */
2915   gfc_conv_loop_setup (&loop);
2916
2917   /* Setup the gfc_se structures.  */
2918   gfc_copy_loopinfo_to_se (&lse, &loop);
2919   gfc_copy_loopinfo_to_se (&rse, &loop);
2920
2921   rse.ss = rss;
2922   gfc_mark_ss_chain_used (rss, 1);
2923   lse.ss = lss;
2924   gfc_mark_ss_chain_used (lss, 1);
2925
2926   /* Start the scalarized loop body.  */
2927   gfc_start_scalarized_body (&loop, &body);
2928
2929   gfc_conv_tmp_array_ref (&lse);
2930   if (cm->ts.type == BT_CHARACTER)
2931     lse.string_length = cm->ts.cl->backend_decl;
2932
2933   gfc_conv_expr (&rse, expr);
2934
2935   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
2936   gfc_add_expr_to_block (&body, tmp);
2937
2938   gcc_assert (rse.ss == gfc_ss_terminator);
2939
2940   /* Generate the copying loops.  */
2941   gfc_trans_scalarizing_loops (&loop, &body);
2942
2943   /* Wrap the whole thing up.  */
2944   gfc_add_block_to_block (&block, &loop.pre);
2945   gfc_add_block_to_block (&block, &loop.post);
2946
2947   for (n = 0; n < cm->as->rank; n++)
2948     mpz_clear (lss->shape[n]);
2949   gfc_free (lss->shape);
2950
2951   gfc_cleanup_loop (&loop);
2952
2953   return gfc_finish_block (&block);
2954 }
2955
2956
2957 /* Assign a single component of a derived type constructor.  */
2958
2959 static tree
2960 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2961 {
2962   gfc_se se;
2963   gfc_se lse;
2964   gfc_ss *rss;
2965   stmtblock_t block;
2966   tree tmp;
2967   tree offset;
2968   int n;
2969
2970   gfc_start_block (&block);
2971
2972   if (cm->pointer)
2973     {
2974       gfc_init_se (&se, NULL);
2975       /* Pointer component.  */
2976       if (cm->dimension)
2977         {
2978           /* Array pointer.  */
2979           if (expr->expr_type == EXPR_NULL)
2980             gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
2981           else
2982             {
2983               rss = gfc_walk_expr (expr);
2984               se.direct_byref = 1;
2985               se.expr = dest;
2986               gfc_conv_expr_descriptor (&se, expr, rss);
2987               gfc_add_block_to_block (&block, &se.pre);
2988               gfc_add_block_to_block (&block, &se.post);
2989             }
2990         }
2991       else
2992         {
2993           /* Scalar pointers.  */
2994           se.want_pointer = 1;
2995           gfc_conv_expr (&se, expr);
2996           gfc_add_block_to_block (&block, &se.pre);
2997           gfc_add_modify_expr (&block, dest,
2998                                fold_convert (TREE_TYPE (dest), se.expr));
2999           gfc_add_block_to_block (&block, &se.post);
3000         }
3001     }
3002   else if (cm->dimension)
3003     {
3004       if (cm->allocatable && expr->expr_type == EXPR_NULL)
3005         gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
3006       else if (cm->allocatable)
3007         {
3008           tree tmp2;
3009
3010           gfc_init_se (&se, NULL);
3011  
3012           rss = gfc_walk_expr (expr);
3013           se.want_pointer = 0;
3014           gfc_conv_expr_descriptor (&se, expr, rss);
3015           gfc_add_block_to_block (&block, &se.pre);
3016
3017           tmp = fold_convert (TREE_TYPE (dest), se.expr);
3018           gfc_add_modify_expr (&block, dest, tmp);
3019
3020           if (cm->ts.type == BT_DERIVED && cm->ts.derived->attr.alloc_comp)
3021             tmp = gfc_copy_alloc_comp (cm->ts.derived, se.expr, dest,
3022                                        cm->as->rank);
3023           else
3024             tmp = gfc_duplicate_allocatable (dest, se.expr,
3025                                              TREE_TYPE(cm->backend_decl),
3026                                              cm->as->rank);
3027
3028           gfc_add_expr_to_block (&block, tmp);
3029
3030           gfc_add_block_to_block (&block, &se.post);
3031           gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
3032
3033           /* Shift the lbound and ubound of temporaries to being unity, rather
3034              than zero, based.  Calculate the offset for all cases.  */
3035           offset = gfc_conv_descriptor_offset (dest);
3036           gfc_add_modify_expr (&block, offset, gfc_index_zero_node);
3037           tmp2 =gfc_create_var (gfc_array_index_type, NULL);
3038           for (n = 0; n < expr->rank; n++)
3039             {
3040               if (expr->expr_type != EXPR_VARIABLE
3041                     && expr->expr_type != EXPR_CONSTANT)
3042                 {
3043                   tree span;
3044                   tmp = gfc_conv_descriptor_ubound (dest, gfc_rank_cst[n]);
3045                   span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
3046                             gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]));
3047                   gfc_add_modify_expr (&block, tmp,
3048                                        fold_build2 (PLUS_EXPR,
3049                                                     gfc_array_index_type,
3050                                                     span, gfc_index_one_node));
3051                   tmp = gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]);
3052                   gfc_add_modify_expr (&block, tmp, gfc_index_one_node);
3053                 }
3054               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3055                                  gfc_conv_descriptor_lbound (dest,
3056                                                              gfc_rank_cst[n]),
3057                                  gfc_conv_descriptor_stride (dest,
3058                                                              gfc_rank_cst[n]));
3059               gfc_add_modify_expr (&block, tmp2, tmp);
3060               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
3061               gfc_add_modify_expr (&block, offset, tmp);
3062             }
3063         }
3064       else
3065         {
3066           tmp = gfc_trans_subarray_assign (dest, cm, expr);
3067           gfc_add_expr_to_block (&block, tmp);
3068         }
3069     }
3070   else if (expr->ts.type == BT_DERIVED)
3071     {
3072       if (expr->expr_type != EXPR_STRUCTURE)
3073         {
3074           gfc_init_se (&se, NULL);
3075           gfc_conv_expr (&se, expr);
3076           gfc_add_modify_expr (&block, dest,
3077                                fold_convert (TREE_TYPE (dest), se.expr));
3078         }
3079       else
3080         {
3081           /* Nested constructors.  */
3082           tmp = gfc_trans_structure_assign (dest, expr);
3083           gfc_add_expr_to_block (&block, tmp);
3084         }
3085     }
3086   else
3087     {
3088       /* Scalar component.  */
3089       gfc_init_se (&se, NULL);
3090       gfc_init_se (&lse, NULL);
3091
3092       gfc_conv_expr (&se, expr);
3093       if (cm->ts.type == BT_CHARACTER)
3094         lse.string_length = cm->ts.cl->backend_decl;
3095       lse.expr = dest;
3096       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
3097       gfc_add_expr_to_block (&block, tmp);
3098     }
3099   return gfc_finish_block (&block);
3100 }
3101
3102 /* Assign a derived type constructor to a variable.  */
3103
3104 static tree
3105 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
3106 {
3107   gfc_constructor *c;
3108   gfc_component *cm;
3109   stmtblock_t block;
3110   tree field;
3111   tree tmp;
3112
3113   gfc_start_block (&block);
3114   cm = expr->ts.derived->components;
3115   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
3116     {
3117       /* Skip absent members in default initializers.  */
3118       if (!c->expr)
3119         continue;
3120
3121       field = cm->backend_decl;
3122       tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
3123       tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
3124       gfc_add_expr_to_block (&block, tmp);
3125     }
3126   return gfc_finish_block (&block);
3127 }
3128
3129 /* Build an expression for a constructor. If init is nonzero then
3130    this is part of a static variable initializer.  */
3131
3132 void
3133 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
3134 {
3135   gfc_constructor *c;
3136   gfc_component *cm;
3137   tree val;
3138   tree type;
3139   tree tmp;
3140   VEC(constructor_elt,gc) *v = NULL;
3141
3142   gcc_assert (se->ss == NULL);
3143   gcc_assert (expr->expr_type == EXPR_STRUCTURE);
3144   type = gfc_typenode_for_spec (&expr->ts);
3145
3146   if (!init)
3147     {
3148       /* Create a temporary variable and fill it in.  */
3149       se->expr = gfc_create_var (type, expr->ts.derived->name);
3150       tmp = gfc_trans_structure_assign (se->expr, expr);
3151       gfc_add_expr_to_block (&se->pre, tmp);
3152       return;
3153     }
3154
3155   cm = expr->ts.derived->components;
3156
3157   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
3158     {
3159       /* Skip absent members in default initializers and allocatable
3160          components.  Although the latter have a default initializer
3161          of EXPR_NULL,... by default, the static nullify is not needed
3162          since this is done every time we come into scope.  */
3163       if (!c->expr || cm->allocatable)
3164         continue;
3165
3166       val = gfc_conv_initializer (c->expr, &cm->ts,
3167           TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
3168
3169       /* Append it to the constructor list.  */
3170       CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
3171     }
3172   se->expr = build_constructor (type, v);
3173 }
3174
3175
3176 /* Translate a substring expression.  */
3177
3178 static void
3179 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
3180 {
3181   gfc_ref *ref;
3182
3183   ref = expr->ref;
3184
3185   gcc_assert (ref->type == REF_SUBSTRING);
3186
3187   se->expr = gfc_build_string_const(expr->value.character.length,
3188                                     expr->value.character.string);
3189   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
3190   TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
3191
3192   gfc_conv_substring(se,ref,expr->ts.kind,NULL,&expr->where);
3193 }
3194
3195
3196 /* Entry point for expression translation.  Evaluates a scalar quantity.
3197    EXPR is the expression to be translated, and SE is the state structure if
3198    called from within the scalarized.  */
3199
3200 void
3201 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
3202 {
3203   if (se->ss && se->ss->expr == expr
3204       && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
3205     {
3206       /* Substitute a scalar expression evaluated outside the scalarization
3207          loop.  */
3208       se->expr = se->ss->data.scalar.expr;
3209       se->string_length = se->ss->string_length;
3210       gfc_advance_se_ss_chain (se);
3211       return;
3212     }
3213
3214   /* We need to convert the expressions for the iso_c_binding derived types.
3215      C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
3216      null_pointer_node.  C_PTR and C_FUNPTR are converted to match the
3217      typespec for the C_PTR and C_FUNPTR symbols, which has already been
3218      updated to be an integer with a kind equal to the size of a (void *).  */
3219   if (expr->ts.type == BT_DERIVED && expr->ts.derived
3220       && expr->ts.derived->attr.is_iso_c)
3221     {
3222       if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
3223           || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
3224         {
3225           /* Set expr_type to EXPR_NULL, which will result in
3226              null_pointer_node being used below.  */
3227           expr->expr_type = EXPR_NULL;
3228         }
3229       else
3230         {
3231           /* Update the type/kind of the expression to be what the new
3232              type/kind are for the updated symbols of C_PTR/C_FUNPTR.  */
3233           expr->ts.type = expr->ts.derived->ts.type;
3234           expr->ts.f90_type = expr->ts.derived->ts.f90_type;
3235           expr->ts.kind = expr->ts.derived->ts.kind;
3236         }
3237     }
3238   
3239   switch (expr->expr_type)
3240     {
3241     case EXPR_OP:
3242       gfc_conv_expr_op (se, expr);
3243       break;
3244
3245     case EXPR_FUNCTION:
3246       gfc_conv_function_expr (se, expr);
3247       break;
3248
3249     case EXPR_CONSTANT:
3250       gfc_conv_constant (se, expr);
3251       break;
3252
3253     case EXPR_VARIABLE:
3254       gfc_conv_variable (se, expr);
3255       break;
3256
3257     case EXPR_NULL:
3258       se->expr = null_pointer_node;
3259       break;
3260
3261     case EXPR_SUBSTRING:
3262       gfc_conv_substring_expr (se, expr);
3263       break;
3264
3265     case EXPR_STRUCTURE:
3266       gfc_conv_structure (se, expr, 0);
3267       break;
3268
3269     case EXPR_ARRAY:
3270       gfc_conv_array_constructor_expr (se, expr);
3271       break;
3272
3273     default:
3274       gcc_unreachable ();
3275       break;
3276     }
3277 }
3278
3279 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
3280    of an assignment.  */
3281 void
3282 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
3283 {
3284   gfc_conv_expr (se, expr);
3285   /* All numeric lvalues should have empty post chains.  If not we need to
3286      figure out a way of rewriting an lvalue so that it has no post chain.  */
3287   gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
3288 }
3289
3290 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
3291    numeric expressions.  Used for scalar values where inserting cleanup code
3292    is inconvenient.  */
3293 void
3294 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
3295 {
3296   tree val;
3297
3298   gcc_assert (expr->ts.type != BT_CHARACTER);
3299   gfc_conv_expr (se, expr);
3300   if (se->post.head)
3301     {
3302       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
3303       gfc_add_modify_expr (&se->pre, val, se->expr);
3304       se->expr = val;
3305       gfc_add_block_to_block (&se->pre, &se->post);
3306     }
3307 }
3308
3309 /* Helper to translate and expression and convert it to a particular type.  */
3310 void
3311 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
3312 {
3313   gfc_conv_expr_val (se, expr);
3314   se->expr = convert (type, se->expr);
3315 }
3316
3317
3318 /* Converts an expression so that it can be passed by reference.  Scalar
3319    values only.  */
3320
3321 void
3322 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
3323 {
3324   tree var;
3325
3326   if (se->ss && se->ss->expr == expr
3327       && se->ss->type == GFC_SS_REFERENCE)
3328     {
3329       se->expr = se->ss->data.scalar.expr;
3330       se->string_length = se->ss->string_length;
3331       gfc_advance_se_ss_chain (se);
3332       return;
3333     }
3334
3335   if (expr->ts.type == BT_CHARACTER)
3336     {
3337       gfc_conv_expr (se, expr);
3338       gfc_conv_string_parameter (se);
3339       return;
3340     }
3341
3342   if (expr->expr_type == EXPR_VARIABLE)
3343     {
3344       se->want_pointer = 1;
3345       gfc_conv_expr (se, expr);
3346       if (se->post.head)
3347         {
3348           var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3349           gfc_add_modify_expr (&se->pre, var, se->expr);
3350           gfc_add_block_to_block (&se->pre, &se->post);
3351           se->expr = var;
3352         }
3353       return;
3354     }
3355
3356   gfc_conv_expr (se, expr);
3357
3358   /* Create a temporary var to hold the value.  */
3359   if (TREE_CONSTANT (se->expr))
3360     {
3361       tree tmp = se->expr;
3362       STRIP_TYPE_NOPS (tmp);
3363       var = build_decl (CONST_DECL, NULL, TREE_TYPE (tmp));
3364       DECL_INITIAL (var) = tmp;
3365       TREE_STATIC (var) = 1;
3366       pushdecl (var);
3367     }
3368   else
3369     {
3370       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3371       gfc_add_modify_expr (&se->pre, var, se->expr);
3372     }
3373   gfc_add_block_to_block (&se->pre, &se->post);
3374
3375   /* Take the address of that value.  */
3376   se->expr = build_fold_addr_expr (var);
3377 }
3378
3379
3380 tree
3381 gfc_trans_pointer_assign (gfc_code * code)
3382 {
3383   return gfc_trans_pointer_assignment (code->expr, code->expr2);
3384 }
3385
3386
3387 /* Generate code for a pointer assignment.  */
3388
3389 tree
3390 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
3391 {
3392   gfc_se lse;
3393   gfc_se rse;
3394   gfc_ss *lss;
3395   gfc_ss *rss;
3396   stmtblock_t block;
3397   tree desc;
3398   tree tmp;
3399
3400   gfc_start_block (&block);
3401
3402   gfc_init_se (&lse, NULL);
3403
3404   lss = gfc_walk_expr (expr1);
3405   rss = gfc_walk_expr (expr2);
3406   if (lss == gfc_ss_terminator)
3407     {
3408       /* Scalar pointers.  */
3409       lse.want_pointer = 1;
3410       gfc_conv_expr (&lse, expr1);
3411       gcc_assert (rss == gfc_ss_terminator);
3412       gfc_init_se (&rse, NULL);
3413       rse.want_pointer = 1;
3414       gfc_conv_expr (&rse, expr2);
3415       gfc_add_block_to_block (&block, &lse.pre);
3416       gfc_add_block_to_block (&block, &rse.pre);
3417       gfc_add_modify_expr (&block, lse.expr,
3418                            fold_convert (TREE_TYPE (lse.expr), rse.expr));
3419       gfc_add_block_to_block (&block, &rse.post);
3420       gfc_add_block_to_block (&block, &lse.post);
3421     }
3422   else
3423     {
3424       /* Array pointer.  */
3425       gfc_conv_expr_descriptor (&lse, expr1, lss);
3426       switch (expr2->expr_type)
3427         {
3428         case EXPR_NULL:
3429           /* Just set the data pointer to null.  */
3430           gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
3431           break;
3432
3433         case EXPR_VARIABLE:
3434           /* Assign directly to the pointer's descriptor.  */
3435           lse.direct_byref = 1;
3436           gfc_conv_expr_descriptor (&lse, expr2, rss);
3437           break;
3438
3439         default:
3440           /* Assign to a temporary descriptor and then copy that
3441              temporary to the pointer.  */
3442           desc = lse.expr;
3443           tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
3444
3445           lse.expr = tmp;
3446           lse.direct_byref = 1;
3447           gfc_conv_expr_descriptor (&lse, expr2, rss);
3448           gfc_add_modify_expr (&lse.pre, desc, tmp);
3449           break;
3450         }
3451       gfc_add_block_to_block (&block, &lse.pre);
3452       gfc_add_block_to_block (&block, &lse.post);
3453     }
3454   return gfc_finish_block (&block);
3455 }
3456
3457
3458 /* Makes sure se is suitable for passing as a function string parameter.  */
3459 /* TODO: Need to check all callers fo this function.  It may be abused.  */
3460
3461 void
3462 gfc_conv_string_parameter (gfc_se * se)
3463 {
3464   tree type;
3465
3466   if (TREE_CODE (se->expr) == STRING_CST)
3467     {
3468       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3469       return;
3470     }
3471
3472   type = TREE_TYPE (se->expr);
3473   if (TYPE_STRING_FLAG (type))
3474     {
3475       gcc_assert (TREE_CODE (se->expr) != INDIRECT_REF);
3476       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3477     }
3478
3479   gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
3480   gcc_assert (se->string_length
3481           && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
3482 }
3483
3484
3485 /* Generate code for assignment of scalar variables.  Includes character
3486    strings and derived types with allocatable components.  */
3487
3488 tree
3489 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
3490                          bool l_is_temp, bool r_is_var)
3491 {
3492   stmtblock_t block;
3493   tree tmp;
3494   tree cond;
3495
3496   gfc_init_block (&block);
3497
3498   if (ts.type == BT_CHARACTER)
3499     {
3500       gcc_assert (lse->string_length != NULL_TREE
3501               && rse->string_length != NULL_TREE);
3502
3503       gfc_conv_string_parameter (lse);
3504       gfc_conv_string_parameter (rse);
3505
3506       gfc_add_block_to_block (&block, &lse->pre);
3507       gfc_add_block_to_block (&block, &rse->pre);
3508
3509       gfc_trans_string_copy (&block, lse->string_length, lse->expr,
3510                              rse->string_length, rse->expr);
3511     }
3512   else if (ts.type == BT_DERIVED && ts.derived->attr.alloc_comp)
3513     {
3514       cond = NULL_TREE;
3515         
3516       /* Are the rhs and the lhs the same?  */
3517       if (r_is_var)
3518         {
3519           cond = fold_build2 (EQ_EXPR, boolean_type_node,
3520                               build_fold_addr_expr (lse->expr),
3521                               build_fold_addr_expr (rse->expr));
3522           cond = gfc_evaluate_now (cond, &lse->pre);
3523         }
3524
3525       /* Deallocate the lhs allocated components as long as it is not
3526          the same as the rhs.  */
3527       if (!l_is_temp)
3528         {
3529           tmp = gfc_deallocate_alloc_comp (ts.derived, lse->expr, 0);
3530           if (r_is_var)
3531             tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3532           gfc_add_expr_to_block (&lse->pre, tmp);
3533         }
3534
3535       if (r_is_var)
3536         {
3537           gfc_add_block_to_block (&block, &lse->pre);
3538           gfc_add_block_to_block (&block, &rse->pre);
3539         }
3540       else
3541         {
3542           gfc_add_block_to_block (&block, &rse->pre);
3543           gfc_add_block_to_block (&block, &lse->pre);
3544         }
3545
3546       gfc_add_modify_expr (&block, lse->expr,
3547                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
3548
3549       /* Do a deep copy if the rhs is a variable, if it is not the
3550          same as the lhs.  */
3551       if (r_is_var)
3552         {
3553           tmp = gfc_copy_alloc_comp (ts.derived, rse->expr, lse->expr, 0);
3554           tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3555           gfc_add_expr_to_block (&block, tmp);
3556         }
3557     }
3558   else
3559     {
3560       gfc_add_block_to_block (&block, &lse->pre);
3561       gfc_add_block_to_block (&block, &rse->pre);
3562
3563       gfc_add_modify_expr (&block, lse->expr,
3564                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
3565     }
3566
3567   gfc_add_block_to_block (&block, &lse->post);
3568   gfc_add_block_to_block (&block, &rse->post);
3569
3570   return gfc_finish_block (&block);
3571 }
3572
3573
3574 /* Try to translate array(:) = func (...), where func is a transformational
3575    array function, without using a temporary.  Returns NULL is this isn't the
3576    case.  */
3577
3578 static tree
3579 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
3580 {
3581   gfc_se se;
3582   gfc_ss *ss;
3583   gfc_ref * ref;
3584   bool seen_array_ref;
3585
3586   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
3587   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
3588     return NULL;
3589
3590   /* Elemental functions don't need a temporary anyway.  */
3591   if (expr2->value.function.esym != NULL
3592       && expr2->value.function.esym->attr.elemental)
3593     return NULL;
3594
3595   /* Fail if EXPR1 can't be expressed as a descriptor.  */
3596   if (gfc_ref_needs_temporary_p (expr1->ref))
3597     return NULL;
3598
3599   /* Functions returning pointers need temporaries.  */
3600   if (expr2->symtree->n.sym->attr.pointer 
3601       || expr2->symtree->n.sym->attr.allocatable)
3602     return NULL;
3603
3604   /* Character array functions need temporaries unless the
3605      character lengths are the same.  */
3606   if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
3607     {
3608       if (expr1->ts.cl->length == NULL
3609             || expr1->ts.cl->length->expr_type != EXPR_CONSTANT)
3610         return NULL;
3611
3612       if (expr2->ts.cl->length == NULL
3613             || expr2->ts.cl->length->expr_type != EXPR_CONSTANT)
3614         return NULL;
3615
3616       if (mpz_cmp (expr1->ts.cl->length->value.integer,
3617                      expr2->ts.cl->length->value.integer) != 0)
3618         return NULL;
3619     }
3620
3621   /* Check that no LHS component references appear during an array
3622      reference. This is needed because we do not have the means to
3623      span any arbitrary stride with an array descriptor. This check
3624      is not needed for the rhs because the function result has to be
3625      a complete type.  */
3626   seen_array_ref = false;
3627   for (ref = expr1->ref; ref; ref = ref->next)
3628     {
3629       if (ref->type == REF_ARRAY)
3630         seen_array_ref= true;
3631       else if (ref->type == REF_COMPONENT && seen_array_ref)
3632         return NULL;
3633     }
3634
3635   /* Check for a dependency.  */
3636   if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
3637                                    expr2->value.function.esym,
3638                                    expr2->value.function.actual))
3639     return NULL;
3640
3641   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
3642      functions.  */
3643   gcc_assert (expr2->value.function.isym
3644               || (gfc_return_by_reference (expr2->value.function.esym)
3645               && expr2->value.function.esym->result->attr.dimension));
3646
3647   ss = gfc_walk_expr (expr1);
3648   gcc_assert (ss != gfc_ss_terminator);
3649   gfc_init_se (&se, NULL);
3650   gfc_start_block (&se.pre);
3651   se.want_pointer = 1;
3652
3653   gfc_conv_array_parameter (&se, expr1, ss, 0);
3654
3655   se.direct_byref = 1;
3656   se.ss = gfc_walk_expr (expr2);
3657   gcc_assert (se.ss != gfc_ss_terminator);
3658   gfc_conv_function_expr (&se, expr2);
3659   gfc_add_block_to_block (&se.pre, &se.post);
3660
3661   return gfc_finish_block (&se.pre);
3662 }
3663
3664 /* Determine whether the given EXPR_CONSTANT is a zero initializer.  */
3665
3666 static bool
3667 is_zero_initializer_p (gfc_expr * expr)
3668 {
3669   if (expr->expr_type != EXPR_CONSTANT)
3670     return false;
3671
3672   /* We ignore constants with prescribed memory representations for now.  */
3673   if (expr->representation.string)
3674     return false;
3675
3676   switch (expr->ts.type)
3677     {
3678     case BT_INTEGER:
3679       return mpz_cmp_si (expr->value.integer, 0) == 0;
3680
3681     case BT_REAL:
3682       return mpfr_zero_p (expr->value.real)
3683              && MPFR_SIGN (expr->value.real) >= 0;
3684
3685     case BT_LOGICAL:
3686       return expr->value.logical == 0;
3687
3688     case BT_COMPLEX:
3689       return mpfr_zero_p (expr->value.complex.r)
3690              && MPFR_SIGN (expr->value.complex.r) >= 0
3691              && mpfr_zero_p (expr->value.complex.i)
3692              && MPFR_SIGN (expr->value.complex.i) >= 0;
3693
3694     default:
3695       break;
3696     }
3697   return false;
3698 }
3699
3700 /* Try to efficiently translate array(:) = 0.  Return NULL if this
3701    can't be done.  */
3702
3703 static tree
3704 gfc_trans_zero_assign (gfc_expr * expr)
3705 {
3706   tree dest, len, type;
3707   tree tmp;
3708   gfc_symbol *sym;
3709
3710   sym = expr->symtree->n.sym;
3711   dest = gfc_get_symbol_decl (sym);
3712
3713   type = TREE_TYPE (dest);
3714   if (POINTER_TYPE_P (type))
3715     type = TREE_TYPE (type);
3716   if (!GFC_ARRAY_TYPE_P (type))
3717     return NULL_TREE;
3718
3719   /* Determine the length of the array.  */
3720   len = GFC_TYPE_ARRAY_SIZE (type);
3721   if (!len || TREE_CODE (len) != INTEGER_CST)
3722     return NULL_TREE;
3723
3724   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3725   len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
3726                      fold_convert (gfc_array_index_type, tmp));
3727
3728   /* Convert arguments to the correct types.  */
3729   if (!POINTER_TYPE_P (TREE_TYPE (dest)))
3730     dest = gfc_build_addr_expr (pvoid_type_node, dest);
3731   else
3732     dest = fold_convert (pvoid_type_node, dest);
3733   len = fold_convert (size_type_node, len);
3734
3735   /* Construct call to __builtin_memset.  */
3736   tmp = build_call_expr (built_in_decls[BUILT_IN_MEMSET],
3737                          3, dest, integer_zero_node, len);
3738   return fold_convert (void_type_node, tmp);
3739 }
3740
3741
3742 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
3743    that constructs the call to __builtin_memcpy.  */
3744
3745 static tree
3746 gfc_build_memcpy_call (tree dst, tree src, tree len)
3747 {
3748   tree tmp;
3749
3750   /* Convert arguments to the correct types.  */
3751   if (!POINTER_TYPE_P (TREE_TYPE (dst)))
3752     dst = gfc_build_addr_expr (pvoid_type_node, dst);
3753   else
3754     dst = fold_convert (pvoid_type_node, dst);
3755
3756   if (!POINTER_TYPE_P (TREE_TYPE (src)))
3757     src = gfc_build_addr_expr (pvoid_type_node, src);
3758   else
3759     src = fold_convert (pvoid_type_node, src);
3760
3761   len = fold_convert (size_type_node, len);
3762
3763   /* Construct call to __builtin_memcpy.  */
3764   tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
3765   return fold_convert (void_type_node, tmp);
3766 }
3767
3768
3769 /* Try to efficiently translate dst(:) = src(:).  Return NULL if this
3770    can't be done.  EXPR1 is the destination/lhs and EXPR2 is the
3771    source/rhs, both are gfc_full_array_ref_p which have been checked for
3772    dependencies.  */
3773
3774 static tree
3775 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
3776 {
3777   tree dst, dlen, dtype;
3778   tree src, slen, stype;
3779   tree tmp;
3780
3781   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
3782   src = gfc_get_symbol_decl (expr2->symtree->n.sym);
3783
3784   dtype = TREE_TYPE (dst);
3785   if (POINTER_TYPE_P (dtype))
3786     dtype = TREE_TYPE (dtype);
3787   stype = TREE_TYPE (src);
3788   if (POINTER_TYPE_P (stype))
3789     stype = TREE_TYPE (stype);
3790
3791   if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
3792     return NULL_TREE;
3793
3794   /* Determine the lengths of the arrays.  */
3795   dlen = GFC_TYPE_ARRAY_SIZE (dtype);
3796   if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
3797     return NULL_TREE;
3798   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
3799   dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
3800                       fold_convert (gfc_array_index_type, tmp));
3801
3802   slen = GFC_TYPE_ARRAY_SIZE (stype);
3803   if (!slen || TREE_CODE (slen) != INTEGER_CST)
3804     return NULL_TREE;
3805   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
3806   slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
3807                       fold_convert (gfc_array_index_type, tmp));
3808
3809   /* Sanity check that they are the same.  This should always be
3810      the case, as we should already have checked for conformance.  */
3811   if (!tree_int_cst_equal (slen, dlen))
3812     return NULL_TREE;
3813
3814   return gfc_build_memcpy_call (dst, src, dlen);
3815 }
3816
3817
3818 /* Try to efficiently translate array(:) = (/ ... /).  Return NULL if
3819    this can't be done.  EXPR1 is the destination/lhs for which
3820    gfc_full_array_ref_p is true, and EXPR2 is the source/rhs.  */
3821
3822 static tree
3823 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
3824 {
3825   unsigned HOST_WIDE_INT nelem;
3826   tree dst, dtype;
3827   tree src, stype;
3828   tree len;
3829   tree tmp;
3830
3831   nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
3832   if (nelem == 0)
3833     return NULL_TREE;
3834
3835   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
3836   dtype = TREE_TYPE (dst);
3837   if (POINTER_TYPE_P (dtype))
3838     dtype = TREE_TYPE (dtype);
3839   if (!GFC_ARRAY_TYPE_P (dtype))
3840     return NULL_TREE;
3841
3842   /* Determine the lengths of the array.  */
3843   len = GFC_TYPE_ARRAY_SIZE (dtype);
3844   if (!len || TREE_CODE (len) != INTEGER_CST)
3845     return NULL_TREE;
3846
3847   /* Confirm that the constructor is the same size.  */
3848   if (compare_tree_int (len, nelem) != 0)
3849     return NULL_TREE;
3850
3851   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
3852   len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
3853                      fold_convert (gfc_array_index_type, tmp));
3854
3855   stype = gfc_typenode_for_spec (&expr2->ts);
3856   src = gfc_build_constant_array_constructor (expr2, stype);
3857
3858   stype = TREE_TYPE (src);
3859   if (POINTER_TYPE_P (stype))
3860     stype = TREE_TYPE (stype);
3861
3862   return gfc_build_memcpy_call (dst, src, len);
3863 }
3864
3865
3866 /* Subroutine of gfc_trans_assignment that actually scalarizes the
3867    assignment.  EXPR1 is the destination/RHS and EXPR2 is the source/LHS.  */
3868
3869 static tree
3870 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
3871 {
3872   gfc_se lse;
3873   gfc_se rse;
3874   gfc_ss *lss;
3875   gfc_ss *lss_section;
3876   gfc_ss *rss;
3877   gfc_loopinfo loop;
3878   tree tmp;
3879   stmtblock_t block;
3880   stmtblock_t body;
3881   bool l_is_temp;
3882
3883   /* Assignment of the form lhs = rhs.  */
3884   gfc_start_block (&block);
3885
3886   gfc_init_se (&lse, NULL);
3887   gfc_init_se (&rse, NULL);
3888
3889   /* Walk the lhs.  */
3890   lss = gfc_walk_expr (expr1);
3891   rss = NULL;
3892   if (lss != gfc_ss_terminator)
3893     {
3894       /* The assignment needs scalarization.  */
3895       lss_section = lss;
3896
3897       /* Find a non-scalar SS from the lhs.  */
3898       while (lss_section != gfc_ss_terminator
3899              && lss_section->type != GFC_SS_SECTION)
3900         lss_section = lss_section->next;
3901
3902       gcc_assert (lss_section != gfc_ss_terminator);
3903
3904       /* Initialize the scalarizer.  */
3905       gfc_init_loopinfo (&loop);
3906
3907       /* Walk the rhs.  */
3908       rss = gfc_walk_expr (expr2);
3909       if (rss == gfc_ss_terminator)
3910         {
3911           /* The rhs is scalar.  Add a ss for the expression.  */
3912           rss = gfc_get_ss ();
3913           rss->next = gfc_ss_terminator;
3914           rss->type = GFC_SS_SCALAR;
3915           rss->expr = expr2;
3916         }
3917       /* Associate the SS with the loop.  */
3918       gfc_add_ss_to_loop (&loop, lss);
3919       gfc_add_ss_to_loop (&loop, rss);
3920
3921       /* Calculate the bounds of the scalarization.  */
3922       gfc_conv_ss_startstride (&loop);
3923       /* Resolve any data dependencies in the statement.  */
3924       gfc_conv_resolve_dependencies (&loop, lss, rss);
3925       /* Setup the scalarizing loops.  */
3926       gfc_conv_loop_setup (&loop);
3927
3928       /* Setup the gfc_se structures.  */
3929       gfc_copy_loopinfo_to_se (&lse, &loop);
3930       gfc_copy_loopinfo_to_se (&rse, &loop);
3931
3932       rse.ss = rss;
3933       gfc_mark_ss_chain_used (rss, 1);
3934       if (loop.temp_ss == NULL)
3935         {
3936           lse.ss = lss;
3937           gfc_mark_ss_chain_used (lss, 1);
3938         }
3939       else
3940         {
3941           lse.ss = loop.temp_ss;
3942           gfc_mark_ss_chain_used (lss, 3);
3943           gfc_mark_ss_chain_used (loop.temp_ss, 3);
3944         }
3945
3946       /* Start the scalarized loop body.  */
3947       gfc_start_scalarized_body (&loop, &body);
3948     }
3949   else
3950     gfc_init_block (&body);
3951
3952   l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
3953
3954   /* Translate the expression.  */
3955   gfc_conv_expr (&rse, expr2);
3956
3957   if (l_is_temp)
3958     {
3959       gfc_conv_tmp_array_ref (&lse);
3960       gfc_advance_se_ss_chain (&lse);
3961     }
3962   else
3963     gfc_conv_expr (&lse, expr1);
3964
3965   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
3966                                  l_is_temp || init_flag,
3967                                  expr2->expr_type == EXPR_VARIABLE);
3968   gfc_add_expr_to_block (&body, tmp);
3969
3970   if (lss == gfc_ss_terminator)
3971     {
3972       /* Use the scalar assignment as is.  */
3973       gfc_add_block_to_block (&block, &body);
3974     }
3975   else
3976     {
3977       gcc_assert (lse.ss == gfc_ss_terminator
3978                   && rse.ss == gfc_ss_terminator);
3979
3980       if (l_is_temp)
3981         {
3982           gfc_trans_scalarized_loop_boundary (&loop, &body);
3983
3984           /* We need to copy the temporary to the actual lhs.  */
3985           gfc_init_se (&lse, NULL);
3986           gfc_init_se (&rse, NULL);
3987           gfc_copy_loopinfo_to_se (&lse, &loop);
3988           gfc_copy_loopinfo_to_se (&rse, &loop);
3989
3990           rse.ss = loop.temp_ss;
3991           lse.ss = lss;
3992
3993           gfc_conv_tmp_array_ref (&rse);
3994           gfc_advance_se_ss_chain (&rse);
3995           gfc_conv_expr (&lse, expr1);
3996
3997           gcc_assert (lse.ss == gfc_ss_terminator
3998                       && rse.ss == gfc_ss_terminator);
3999
4000           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4001                                          false, false);
4002           gfc_add_expr_to_block (&body, tmp);
4003         }
4004
4005       /* Generate the copying loops.  */
4006       gfc_trans_scalarizing_loops (&loop, &body);
4007
4008       /* Wrap the whole thing up.  */
4009       gfc_add_block_to_block (&block, &loop.pre);
4010       gfc_add_block_to_block (&block, &loop.post);
4011
4012       gfc_cleanup_loop (&loop);
4013     }
4014
4015   return gfc_finish_block (&block);
4016 }
4017
4018
4019 /* Check whether EXPR, which is an EXPR_VARIABLE, is a copyable array.  */
4020
4021 static bool
4022 copyable_array_p (gfc_expr * expr)
4023 {
4024   /* First check it's an array.  */
4025   if (expr->rank < 1 || !expr->ref)
4026     return false;
4027
4028   /* Next check that it's of a simple enough type.  */
4029   switch (expr->ts.type)
4030     {
4031     case BT_INTEGER:
4032     case BT_REAL:
4033     case BT_COMPLEX:
4034     case BT_LOGICAL:
4035       return true;
4036
4037     case BT_CHARACTER:
4038       return false;
4039
4040     case BT_DERIVED:
4041       return !expr->ts.derived->attr.alloc_comp;
4042
4043     default:
4044       break;
4045     }
4046
4047   return false;
4048 }
4049
4050 /* Translate an assignment.  */
4051
4052 tree
4053 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
4054 {
4055   tree tmp;
4056
4057   /* Special case a single function returning an array.  */
4058   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
4059     {
4060       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
4061       if (tmp)
4062         return tmp;
4063     }
4064
4065   /* Special case assigning an array to zero.  */
4066   if (expr1->expr_type == EXPR_VARIABLE
4067       && expr1->rank > 0
4068       && expr1->ref
4069       && expr1->ref->next == NULL
4070       && gfc_full_array_ref_p (expr1->ref)
4071       && is_zero_initializer_p (expr2))
4072     {
4073       tmp = gfc_trans_zero_assign (expr1);
4074       if (tmp)
4075         return tmp;
4076     }
4077
4078   /* Special case copying one array to another.  */
4079   if (expr1->expr_type == EXPR_VARIABLE
4080       && copyable_array_p (expr1)
4081       && gfc_full_array_ref_p (expr1->ref)
4082       && expr2->expr_type == EXPR_VARIABLE
4083       && copyable_array_p (expr2)
4084       && gfc_full_array_ref_p (expr2->ref)
4085       && gfc_compare_types (&expr1->ts, &expr2->ts)
4086       && !gfc_check_dependency (expr1, expr2, 0))
4087     {
4088       tmp = gfc_trans_array_copy (expr1, expr2);
4089       if (tmp)
4090         return tmp;
4091     }
4092
4093   /* Special case initializing an array from a constant array constructor.  */
4094   if (expr1->expr_type == EXPR_VARIABLE
4095       && copyable_array_p (expr1)
4096       && gfc_full_array_ref_p (expr1->ref)
4097       && expr2->expr_type == EXPR_ARRAY
4098       && gfc_compare_types (&expr1->ts, &expr2->ts))
4099     {
4100       tmp = gfc_trans_array_constructor_copy (expr1, expr2);
4101       if (tmp)
4102         return tmp;
4103     }
4104
4105   /* Fallback to the scalarizer to generate explicit loops.  */
4106   return gfc_trans_assignment_1 (expr1, expr2, init_flag);
4107 }
4108
4109 tree
4110 gfc_trans_init_assign (gfc_code * code)
4111 {
4112   return gfc_trans_assignment (code->expr, code->expr2, true);
4113 }
4114
4115 tree
4116 gfc_trans_assign (gfc_code * code)
4117 {
4118   return gfc_trans_assignment (code->expr, code->expr2, false);
4119 }