OSDN Git Service

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