OSDN Git Service

2007-07-17 Paul Thomas <pault@gcc.gnu.org>
[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_EQ_OS:
1106     case INTRINSIC_EQV:
1107       code = EQ_EXPR;
1108       checkstring = 1;
1109       lop = 1;
1110       break;
1111
1112     case INTRINSIC_NE:
1113     case INTRINSIC_NE_OS:
1114     case INTRINSIC_NEQV:
1115       code = NE_EXPR;
1116       checkstring = 1;
1117       lop = 1;
1118       break;
1119
1120     case INTRINSIC_GT:
1121     case INTRINSIC_GT_OS:
1122       code = GT_EXPR;
1123       checkstring = 1;
1124       lop = 1;
1125       break;
1126
1127     case INTRINSIC_GE:
1128     case INTRINSIC_GE_OS:
1129       code = GE_EXPR;
1130       checkstring = 1;
1131       lop = 1;
1132       break;
1133
1134     case INTRINSIC_LT:
1135     case INTRINSIC_LT_OS:
1136       code = LT_EXPR;
1137       checkstring = 1;
1138       lop = 1;
1139       break;
1140
1141     case INTRINSIC_LE:
1142     case INTRINSIC_LE_OS:
1143       code = LE_EXPR;
1144       checkstring = 1;
1145       lop = 1;
1146       break;
1147
1148     case INTRINSIC_USER:
1149     case INTRINSIC_ASSIGN:
1150       /* These should be converted into function calls by the frontend.  */
1151       gcc_unreachable ();
1152
1153     default:
1154       fatal_error ("Unknown intrinsic op");
1155       return;
1156     }
1157
1158   /* The only exception to this is **, which is handled separately anyway.  */
1159   gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
1160
1161   if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
1162     checkstring = 0;
1163
1164   /* lhs */
1165   gfc_init_se (&lse, se);
1166   gfc_conv_expr (&lse, expr->value.op.op1);
1167   gfc_add_block_to_block (&se->pre, &lse.pre);
1168
1169   /* rhs */
1170   gfc_init_se (&rse, se);
1171   gfc_conv_expr (&rse, expr->value.op.op2);
1172   gfc_add_block_to_block (&se->pre, &rse.pre);
1173
1174   if (checkstring)
1175     {
1176       gfc_conv_string_parameter (&lse);
1177       gfc_conv_string_parameter (&rse);
1178
1179       lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
1180                                            rse.string_length, rse.expr);
1181       rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
1182       gfc_add_block_to_block (&lse.post, &rse.post);
1183     }
1184
1185   type = gfc_typenode_for_spec (&expr->ts);
1186
1187   if (lop)
1188     {
1189       /* The result of logical ops is always boolean_type_node.  */
1190       tmp = fold_build2 (code, type, lse.expr, rse.expr);
1191       se->expr = convert (type, tmp);
1192     }
1193   else
1194     se->expr = fold_build2 (code, type, lse.expr, rse.expr);
1195
1196   /* Add the post blocks.  */
1197   gfc_add_block_to_block (&se->post, &rse.post);
1198   gfc_add_block_to_block (&se->post, &lse.post);
1199 }
1200
1201 /* If a string's length is one, we convert it to a single character.  */
1202
1203 static tree
1204 gfc_to_single_character (tree len, tree str)
1205 {
1206   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
1207
1208   if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
1209     && TREE_INT_CST_HIGH (len) == 0)
1210     {
1211       str = fold_convert (pchar_type_node, str);
1212       return build_fold_indirect_ref (str);
1213     }
1214
1215   return NULL_TREE;
1216 }
1217
1218 /* Compare two strings. If they are all single characters, the result is the
1219    subtraction of them. Otherwise, we build a library call.  */
1220
1221 tree
1222 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2)
1223 {
1224   tree sc1;
1225   tree sc2;
1226   tree type;
1227   tree tmp;
1228
1229   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
1230   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
1231
1232   type = gfc_get_int_type (gfc_default_integer_kind);
1233
1234   sc1 = gfc_to_single_character (len1, str1);
1235   sc2 = gfc_to_single_character (len2, str2);
1236
1237   /* Deal with single character specially.  */
1238   if (sc1 != NULL_TREE && sc2 != NULL_TREE)
1239     {
1240       sc1 = fold_convert (type, sc1);
1241       sc2 = fold_convert (type, sc2);
1242       tmp = fold_build2 (MINUS_EXPR, type, sc1, sc2);
1243     }
1244    else
1245      /* Build a call for the comparison.  */
1246      tmp = build_call_expr (gfor_fndecl_compare_string, 4,
1247                             len1, str1, len2, str2);
1248   return tmp;
1249 }
1250
1251 static void
1252 gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
1253 {
1254   tree tmp;
1255
1256   if (sym->attr.dummy)
1257     {
1258       tmp = gfc_get_symbol_decl (sym);
1259       gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1260               && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
1261     }
1262   else
1263     {
1264       if (!sym->backend_decl)
1265         sym->backend_decl = gfc_get_extern_function_decl (sym);
1266
1267       tmp = sym->backend_decl;
1268       if (sym->attr.cray_pointee)
1269         tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
1270                        gfc_get_symbol_decl (sym->cp_pointer));
1271       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1272         {
1273           gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1274           tmp = build_fold_addr_expr (tmp);
1275         }
1276     }
1277   se->expr = tmp;
1278 }
1279
1280
1281 /* Translate the call for an elemental subroutine call used in an operator
1282    assignment.  This is a simplified version of gfc_conv_function_call.  */
1283
1284 tree
1285 gfc_conv_operator_assign (gfc_se *lse, gfc_se *rse, gfc_symbol *sym)
1286 {
1287   tree args;
1288   tree tmp;
1289   gfc_se se;
1290   stmtblock_t block;
1291
1292   /* Only elemental subroutines with two arguments.  */
1293   gcc_assert (sym->attr.elemental && sym->attr.subroutine);
1294   gcc_assert (sym->formal->next->next == NULL);
1295
1296   gfc_init_block (&block);
1297
1298   gfc_add_block_to_block (&block, &lse->pre);
1299   gfc_add_block_to_block (&block, &rse->pre);
1300
1301   /* Build the argument list for the call, including hidden string lengths.  */
1302   args = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (lse->expr));
1303   args = gfc_chainon_list (args, build_fold_addr_expr (rse->expr));
1304   if (lse->string_length != NULL_TREE)
1305     args = gfc_chainon_list (args, lse->string_length);
1306   if (rse->string_length != NULL_TREE)
1307     args = gfc_chainon_list (args, rse->string_length);    
1308
1309   /* Build the function call.  */
1310   gfc_init_se (&se, NULL);
1311   gfc_conv_function_val (&se, sym);
1312   tmp = TREE_TYPE (TREE_TYPE (TREE_TYPE (se.expr)));
1313   tmp = build_call_list (tmp, se.expr, args);
1314   gfc_add_expr_to_block (&block, tmp);
1315
1316   gfc_add_block_to_block (&block, &lse->post);
1317   gfc_add_block_to_block (&block, &rse->post);
1318
1319   return gfc_finish_block (&block);
1320 }
1321
1322
1323 /* Initialize MAPPING.  */
1324
1325 void
1326 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
1327 {
1328   mapping->syms = NULL;
1329   mapping->charlens = NULL;
1330 }
1331
1332
1333 /* Free all memory held by MAPPING (but not MAPPING itself).  */
1334
1335 void
1336 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
1337 {
1338   gfc_interface_sym_mapping *sym;
1339   gfc_interface_sym_mapping *nextsym;
1340   gfc_charlen *cl;
1341   gfc_charlen *nextcl;
1342
1343   for (sym = mapping->syms; sym; sym = nextsym)
1344     {
1345       nextsym = sym->next;
1346       gfc_free_symbol (sym->new->n.sym);
1347       gfc_free (sym->new);
1348       gfc_free (sym);
1349     }
1350   for (cl = mapping->charlens; cl; cl = nextcl)
1351     {
1352       nextcl = cl->next;
1353       gfc_free_expr (cl->length);
1354       gfc_free (cl);
1355     }
1356 }
1357
1358
1359 /* Return a copy of gfc_charlen CL.  Add the returned structure to
1360    MAPPING so that it will be freed by gfc_free_interface_mapping.  */
1361
1362 static gfc_charlen *
1363 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
1364                                    gfc_charlen * cl)
1365 {
1366   gfc_charlen *new;
1367
1368   new = gfc_get_charlen ();
1369   new->next = mapping->charlens;
1370   new->length = gfc_copy_expr (cl->length);
1371
1372   mapping->charlens = new;
1373   return new;
1374 }
1375
1376
1377 /* A subroutine of gfc_add_interface_mapping.  Return a descriptorless
1378    array variable that can be used as the actual argument for dummy
1379    argument SYM.  Add any initialization code to BLOCK.  PACKED is as
1380    for gfc_get_nodesc_array_type and DATA points to the first element
1381    in the passed array.  */
1382
1383 static tree
1384 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
1385                                  gfc_packed packed, tree data)
1386 {
1387   tree type;
1388   tree var;
1389
1390   type = gfc_typenode_for_spec (&sym->ts);
1391   type = gfc_get_nodesc_array_type (type, sym->as, packed);
1392
1393   var = gfc_create_var (type, "ifm");
1394   gfc_add_modify_expr (block, var, fold_convert (type, data));
1395
1396   return var;
1397 }
1398
1399
1400 /* A subroutine of gfc_add_interface_mapping.  Set the stride, upper bounds
1401    and offset of descriptorless array type TYPE given that it has the same
1402    size as DESC.  Add any set-up code to BLOCK.  */
1403
1404 static void
1405 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
1406 {
1407   int n;
1408   tree dim;
1409   tree offset;
1410   tree tmp;
1411
1412   offset = gfc_index_zero_node;
1413   for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
1414     {
1415       dim = gfc_rank_cst[n];
1416       GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
1417       if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
1418         {
1419           GFC_TYPE_ARRAY_LBOUND (type, n)
1420                 = gfc_conv_descriptor_lbound (desc, dim);
1421           GFC_TYPE_ARRAY_UBOUND (type, n)
1422                 = gfc_conv_descriptor_ubound (desc, dim);
1423         }
1424       else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
1425         {
1426           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1427                              gfc_conv_descriptor_ubound (desc, dim),
1428                              gfc_conv_descriptor_lbound (desc, dim));
1429           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1430                              GFC_TYPE_ARRAY_LBOUND (type, n),
1431                              tmp);
1432           tmp = gfc_evaluate_now (tmp, block);
1433           GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
1434         }
1435       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
1436                          GFC_TYPE_ARRAY_LBOUND (type, n),
1437                          GFC_TYPE_ARRAY_STRIDE (type, n));
1438       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
1439     }
1440   offset = gfc_evaluate_now (offset, block);
1441   GFC_TYPE_ARRAY_OFFSET (type) = offset;
1442 }
1443
1444
1445 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
1446    in SE.  The caller may still use se->expr and se->string_length after
1447    calling this function.  */
1448
1449 void
1450 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
1451                            gfc_symbol * sym, gfc_se * se)
1452 {
1453   gfc_interface_sym_mapping *sm;
1454   tree desc;
1455   tree tmp;
1456   tree value;
1457   gfc_symbol *new_sym;
1458   gfc_symtree *root;
1459   gfc_symtree *new_symtree;
1460
1461   /* Create a new symbol to represent the actual argument.  */
1462   new_sym = gfc_new_symbol (sym->name, NULL);
1463   new_sym->ts = sym->ts;
1464   new_sym->attr.referenced = 1;
1465   new_sym->attr.dimension = sym->attr.dimension;
1466   new_sym->attr.pointer = sym->attr.pointer;
1467   new_sym->attr.allocatable = sym->attr.allocatable;
1468   new_sym->attr.flavor = sym->attr.flavor;
1469
1470   /* Create a fake symtree for it.  */
1471   root = NULL;
1472   new_symtree = gfc_new_symtree (&root, sym->name);
1473   new_symtree->n.sym = new_sym;
1474   gcc_assert (new_symtree == root);
1475
1476   /* Create a dummy->actual mapping.  */
1477   sm = gfc_getmem (sizeof (*sm));
1478   sm->next = mapping->syms;
1479   sm->old = sym;
1480   sm->new = new_symtree;
1481   mapping->syms = sm;
1482
1483   /* Stabilize the argument's value.  */
1484   se->expr = gfc_evaluate_now (se->expr, &se->pre);
1485
1486   if (sym->ts.type == BT_CHARACTER)
1487     {
1488       /* Create a copy of the dummy argument's length.  */
1489       new_sym->ts.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.cl);
1490
1491       /* If the length is specified as "*", record the length that
1492          the caller is passing.  We should use the callee's length
1493          in all other cases.  */
1494       if (!new_sym->ts.cl->length)
1495         {
1496           se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
1497           new_sym->ts.cl->backend_decl = se->string_length;
1498         }
1499     }
1500
1501   /* Use the passed value as-is if the argument is a function.  */
1502   if (sym->attr.flavor == FL_PROCEDURE)
1503     value = se->expr;
1504
1505   /* If the argument is either a string or a pointer to a string,
1506      convert it to a boundless character type.  */
1507   else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
1508     {
1509       tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
1510       tmp = build_pointer_type (tmp);
1511       if (sym->attr.pointer)
1512         value = build_fold_indirect_ref (se->expr);
1513       else
1514         value = se->expr;
1515       value = fold_convert (tmp, value);
1516     }
1517
1518   /* If the argument is a scalar, a pointer to an array or an allocatable,
1519      dereference it.  */
1520   else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
1521     value = build_fold_indirect_ref (se->expr);
1522   
1523   /* For character(*), use the actual argument's descriptor.  */  
1524   else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.cl->length)
1525     value = build_fold_indirect_ref (se->expr);
1526
1527   /* If the argument is an array descriptor, use it to determine
1528      information about the actual argument's shape.  */
1529   else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
1530            && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
1531     {
1532       /* Get the actual argument's descriptor.  */
1533       desc = build_fold_indirect_ref (se->expr);
1534
1535       /* Create the replacement variable.  */
1536       tmp = gfc_conv_descriptor_data_get (desc);
1537       value = gfc_get_interface_mapping_array (&se->pre, sym,
1538                                                PACKED_NO, tmp);
1539
1540       /* Use DESC to work out the upper bounds, strides and offset.  */
1541       gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
1542     }
1543   else
1544     /* Otherwise we have a packed array.  */
1545     value = gfc_get_interface_mapping_array (&se->pre, sym,
1546                                              PACKED_FULL, se->expr);
1547
1548   new_sym->backend_decl = value;
1549 }
1550
1551
1552 /* Called once all dummy argument mappings have been added to MAPPING,
1553    but before the mapping is used to evaluate expressions.  Pre-evaluate
1554    the length of each argument, adding any initialization code to PRE and
1555    any finalization code to POST.  */
1556
1557 void
1558 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
1559                               stmtblock_t * pre, stmtblock_t * post)
1560 {
1561   gfc_interface_sym_mapping *sym;
1562   gfc_expr *expr;
1563   gfc_se se;
1564
1565   for (sym = mapping->syms; sym; sym = sym->next)
1566     if (sym->new->n.sym->ts.type == BT_CHARACTER
1567         && !sym->new->n.sym->ts.cl->backend_decl)
1568       {
1569         expr = sym->new->n.sym->ts.cl->length;
1570         gfc_apply_interface_mapping_to_expr (mapping, expr);
1571         gfc_init_se (&se, NULL);
1572         gfc_conv_expr (&se, expr);
1573
1574         se.expr = gfc_evaluate_now (se.expr, &se.pre);
1575         gfc_add_block_to_block (pre, &se.pre);
1576         gfc_add_block_to_block (post, &se.post);
1577
1578         sym->new->n.sym->ts.cl->backend_decl = se.expr;
1579       }
1580 }
1581
1582
1583 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1584    constructor C.  */
1585
1586 static void
1587 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
1588                                      gfc_constructor * c)
1589 {
1590   for (; c; c = c->next)
1591     {
1592       gfc_apply_interface_mapping_to_expr (mapping, c->expr);
1593       if (c->iterator)
1594         {
1595           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
1596           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
1597           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
1598         }
1599     }
1600 }
1601
1602
1603 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1604    reference REF.  */
1605
1606 static void
1607 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
1608                                     gfc_ref * ref)
1609 {
1610   int n;
1611
1612   for (; ref; ref = ref->next)
1613     switch (ref->type)
1614       {
1615       case REF_ARRAY:
1616         for (n = 0; n < ref->u.ar.dimen; n++)
1617           {
1618             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
1619             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
1620             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
1621           }
1622         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
1623         break;
1624
1625       case REF_COMPONENT:
1626         break;
1627
1628       case REF_SUBSTRING:
1629         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
1630         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
1631         break;
1632       }
1633 }
1634
1635
1636 /* EXPR is a copy of an expression that appeared in the interface
1637    associated with MAPPING.  Walk it recursively looking for references to
1638    dummy arguments that MAPPING maps to actual arguments.  Replace each such
1639    reference with a reference to the associated actual argument.  */
1640
1641 static int
1642 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
1643                                      gfc_expr * expr)
1644 {
1645   gfc_interface_sym_mapping *sym;
1646   gfc_actual_arglist *actual;
1647   int seen_result = 0;
1648
1649   if (!expr)
1650     return 0;
1651
1652   /* Copying an expression does not copy its length, so do that here.  */
1653   if (expr->ts.type == BT_CHARACTER && expr->ts.cl)
1654     {
1655       expr->ts.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.cl);
1656       gfc_apply_interface_mapping_to_expr (mapping, expr->ts.cl->length);
1657     }
1658
1659   /* Apply the mapping to any references.  */
1660   gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
1661
1662   /* ...and to the expression's symbol, if it has one.  */
1663   if (expr->symtree)
1664     for (sym = mapping->syms; sym; sym = sym->next)
1665       if (sym->old == expr->symtree->n.sym)
1666         expr->symtree = sym->new;
1667
1668   /* ...and to subexpressions in expr->value.  */
1669   switch (expr->expr_type)
1670     {
1671     case EXPR_VARIABLE:
1672       if (expr->symtree->n.sym->attr.result)
1673         seen_result = 1;
1674     case EXPR_CONSTANT:
1675     case EXPR_NULL:
1676     case EXPR_SUBSTRING:
1677       break;
1678
1679     case EXPR_OP:
1680       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
1681       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
1682       break;
1683
1684     case EXPR_FUNCTION:
1685       if (expr->value.function.esym == NULL
1686             && expr->value.function.isym != NULL
1687             && expr->value.function.isym->id == GFC_ISYM_LEN
1688             && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE
1689             && gfc_apply_interface_mapping_to_expr (mapping,
1690                         expr->value.function.actual->expr))
1691         {
1692           gfc_expr *new_expr;
1693           new_expr = gfc_copy_expr (expr->value.function.actual->expr->ts.cl->length);
1694           *expr = *new_expr;
1695           gfc_free (new_expr);
1696           gfc_apply_interface_mapping_to_expr (mapping, expr);
1697           break;
1698         }
1699
1700       for (sym = mapping->syms; sym; sym = sym->next)
1701         if (sym->old == expr->value.function.esym)
1702           expr->value.function.esym = sym->new->n.sym;
1703
1704       for (actual = expr->value.function.actual; actual; actual = actual->next)
1705         gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
1706       break;
1707
1708     case EXPR_ARRAY:
1709     case EXPR_STRUCTURE:
1710       gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
1711       break;
1712     }
1713   return seen_result;
1714 }
1715
1716
1717 /* Evaluate interface expression EXPR using MAPPING.  Store the result
1718    in SE.  */
1719
1720 void
1721 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
1722                              gfc_se * se, gfc_expr * expr)
1723 {
1724   expr = gfc_copy_expr (expr);
1725   gfc_apply_interface_mapping_to_expr (mapping, expr);
1726   gfc_conv_expr (se, expr);
1727   se->expr = gfc_evaluate_now (se->expr, &se->pre);
1728   gfc_free_expr (expr);
1729 }
1730
1731 /* Returns a reference to a temporary array into which a component of
1732    an actual argument derived type array is copied and then returned
1733    after the function call.
1734    TODO Get rid of this kludge, when array descriptors are capable of
1735    handling arrays with a bigger stride in bytes than size.  */
1736
1737 void
1738 gfc_conv_aliased_arg (gfc_se * parmse, gfc_expr * expr,
1739                       int g77, sym_intent intent)
1740 {
1741   gfc_se lse;
1742   gfc_se rse;
1743   gfc_ss *lss;
1744   gfc_ss *rss;
1745   gfc_loopinfo loop;
1746   gfc_loopinfo loop2;
1747   gfc_ss_info *info;
1748   tree offset;
1749   tree tmp_index;
1750   tree tmp;
1751   tree base_type;
1752   stmtblock_t body;
1753   int n;
1754
1755   gcc_assert (expr->expr_type == EXPR_VARIABLE);
1756
1757   gfc_init_se (&lse, NULL);
1758   gfc_init_se (&rse, NULL);
1759
1760   /* Walk the argument expression.  */
1761   rss = gfc_walk_expr (expr);
1762
1763   gcc_assert (rss != gfc_ss_terminator);
1764  
1765   /* Initialize the scalarizer.  */
1766   gfc_init_loopinfo (&loop);
1767   gfc_add_ss_to_loop (&loop, rss);
1768
1769   /* Calculate the bounds of the scalarization.  */
1770   gfc_conv_ss_startstride (&loop);
1771
1772   /* Build an ss for the temporary.  */
1773   base_type = gfc_typenode_for_spec (&expr->ts);
1774   if (GFC_ARRAY_TYPE_P (base_type)
1775                 || GFC_DESCRIPTOR_TYPE_P (base_type))
1776     base_type = gfc_get_element_type (base_type);
1777
1778   loop.temp_ss = gfc_get_ss ();;
1779   loop.temp_ss->type = GFC_SS_TEMP;
1780   loop.temp_ss->data.temp.type = base_type;
1781
1782   if (expr->ts.type == BT_CHARACTER)
1783     {
1784       gfc_ref *char_ref = expr->ref;
1785
1786       for (; char_ref; char_ref = char_ref->next)
1787         if (char_ref->type == REF_SUBSTRING)
1788           {
1789             gfc_se tmp_se;
1790
1791             expr->ts.cl = gfc_get_charlen ();
1792             expr->ts.cl->next = char_ref->u.ss.length->next;
1793             char_ref->u.ss.length->next = expr->ts.cl;
1794
1795             gfc_init_se (&tmp_se, NULL);
1796             gfc_conv_expr_type (&tmp_se, char_ref->u.ss.end,
1797                                 gfc_array_index_type);
1798             tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1799                                tmp_se.expr, gfc_index_one_node);
1800             tmp = gfc_evaluate_now (tmp, &parmse->pre);
1801             gfc_init_se (&tmp_se, NULL);
1802             gfc_conv_expr_type (&tmp_se, char_ref->u.ss.start,
1803                                 gfc_array_index_type);
1804             tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1805                                tmp, tmp_se.expr);
1806             expr->ts.cl->backend_decl = tmp;
1807
1808             break;
1809           }
1810       loop.temp_ss->data.temp.type
1811                 = gfc_typenode_for_spec (&expr->ts);
1812       loop.temp_ss->string_length = expr->ts.cl->backend_decl;
1813     }
1814
1815   loop.temp_ss->data.temp.dimen = loop.dimen;
1816   loop.temp_ss->next = gfc_ss_terminator;
1817
1818   /* Associate the SS with the loop.  */
1819   gfc_add_ss_to_loop (&loop, loop.temp_ss);
1820
1821   /* Setup the scalarizing loops.  */
1822   gfc_conv_loop_setup (&loop);
1823
1824   /* Pass the temporary descriptor back to the caller.  */
1825   info = &loop.temp_ss->data.info;
1826   parmse->expr = info->descriptor;
1827
1828   /* Setup the gfc_se structures.  */
1829   gfc_copy_loopinfo_to_se (&lse, &loop);
1830   gfc_copy_loopinfo_to_se (&rse, &loop);
1831
1832   rse.ss = rss;
1833   lse.ss = loop.temp_ss;
1834   gfc_mark_ss_chain_used (rss, 1);
1835   gfc_mark_ss_chain_used (loop.temp_ss, 1);
1836
1837   /* Start the scalarized loop body.  */
1838   gfc_start_scalarized_body (&loop, &body);
1839
1840   /* Translate the expression.  */
1841   gfc_conv_expr (&rse, expr);
1842
1843   gfc_conv_tmp_array_ref (&lse);
1844   gfc_advance_se_ss_chain (&lse);
1845
1846   if (intent != INTENT_OUT)
1847     {
1848       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false);
1849       gfc_add_expr_to_block (&body, tmp);
1850       gcc_assert (rse.ss == gfc_ss_terminator);
1851       gfc_trans_scalarizing_loops (&loop, &body);
1852     }
1853   else
1854     {
1855       /* Make sure that the temporary declaration survives by merging
1856        all the loop declarations into the current context.  */
1857       for (n = 0; n < loop.dimen; n++)
1858         {
1859           gfc_merge_block_scope (&body);
1860           body = loop.code[loop.order[n]];
1861         }
1862       gfc_merge_block_scope (&body);
1863     }
1864
1865   /* Add the post block after the second loop, so that any
1866      freeing of allocated memory is done at the right time.  */
1867   gfc_add_block_to_block (&parmse->pre, &loop.pre);
1868
1869   /**********Copy the temporary back again.*********/
1870
1871   gfc_init_se (&lse, NULL);
1872   gfc_init_se (&rse, NULL);
1873
1874   /* Walk the argument expression.  */
1875   lss = gfc_walk_expr (expr);
1876   rse.ss = loop.temp_ss;
1877   lse.ss = lss;
1878
1879   /* Initialize the scalarizer.  */
1880   gfc_init_loopinfo (&loop2);
1881   gfc_add_ss_to_loop (&loop2, lss);
1882
1883   /* Calculate the bounds of the scalarization.  */
1884   gfc_conv_ss_startstride (&loop2);
1885
1886   /* Setup the scalarizing loops.  */
1887   gfc_conv_loop_setup (&loop2);
1888
1889   gfc_copy_loopinfo_to_se (&lse, &loop2);
1890   gfc_copy_loopinfo_to_se (&rse, &loop2);
1891
1892   gfc_mark_ss_chain_used (lss, 1);
1893   gfc_mark_ss_chain_used (loop.temp_ss, 1);
1894
1895   /* Declare the variable to hold the temporary offset and start the
1896      scalarized loop body.  */
1897   offset = gfc_create_var (gfc_array_index_type, NULL);
1898   gfc_start_scalarized_body (&loop2, &body);
1899
1900   /* Build the offsets for the temporary from the loop variables.  The
1901      temporary array has lbounds of zero and strides of one in all
1902      dimensions, so this is very simple.  The offset is only computed
1903      outside the innermost loop, so the overall transfer could be
1904      optimized further.  */
1905   info = &rse.ss->data.info;
1906
1907   tmp_index = gfc_index_zero_node;
1908   for (n = info->dimen - 1; n > 0; n--)
1909     {
1910       tree tmp_str;
1911       tmp = rse.loop->loopvar[n];
1912       tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1913                          tmp, rse.loop->from[n]);
1914       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1915                          tmp, tmp_index);
1916
1917       tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1918                              rse.loop->to[n-1], rse.loop->from[n-1]);
1919       tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1920                              tmp_str, gfc_index_one_node);
1921
1922       tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
1923                                tmp, tmp_str);
1924     }
1925
1926   tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1927                            tmp_index, rse.loop->from[0]);
1928   gfc_add_modify_expr (&rse.loop->code[0], offset, tmp_index);
1929
1930   tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1931                            rse.loop->loopvar[0], offset);
1932
1933   /* Now use the offset for the reference.  */
1934   tmp = build_fold_indirect_ref (info->data);
1935   rse.expr = gfc_build_array_ref (tmp, tmp_index);
1936
1937   if (expr->ts.type == BT_CHARACTER)
1938     rse.string_length = expr->ts.cl->backend_decl;
1939
1940   gfc_conv_expr (&lse, expr);
1941
1942   gcc_assert (lse.ss == gfc_ss_terminator);
1943
1944   tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
1945   gfc_add_expr_to_block (&body, tmp);
1946   
1947   /* Generate the copying loops.  */
1948   gfc_trans_scalarizing_loops (&loop2, &body);
1949
1950   /* Wrap the whole thing up by adding the second loop to the post-block
1951      and following it by the post-block of the first loop.  In this way,
1952      if the temporary needs freeing, it is done after use!  */
1953   if (intent != INTENT_IN)
1954     {
1955       gfc_add_block_to_block (&parmse->post, &loop2.pre);
1956       gfc_add_block_to_block (&parmse->post, &loop2.post);
1957     }
1958
1959   gfc_add_block_to_block (&parmse->post, &loop.post);
1960
1961   gfc_cleanup_loop (&loop);
1962   gfc_cleanup_loop (&loop2);
1963
1964   /* Pass the string length to the argument expression.  */
1965   if (expr->ts.type == BT_CHARACTER)
1966     parmse->string_length = expr->ts.cl->backend_decl;
1967
1968   /* We want either the address for the data or the address of the descriptor,
1969      depending on the mode of passing array arguments.  */
1970   if (g77)
1971     parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
1972   else
1973     parmse->expr = build_fold_addr_expr (parmse->expr);
1974
1975   return;
1976 }
1977
1978 /* Is true if an array reference is followed by a component or substring
1979    reference.  */
1980
1981 bool
1982 is_aliased_array (gfc_expr * e)
1983 {
1984   gfc_ref * ref;
1985   bool seen_array;
1986
1987   seen_array = false;   
1988   for (ref = e->ref; ref; ref = ref->next)
1989     {
1990       if (ref->type == REF_ARRAY
1991             && ref->u.ar.type != AR_ELEMENT)
1992         seen_array = true;
1993
1994       if (seen_array
1995             && ref->type != REF_ARRAY)
1996         return seen_array;
1997     }
1998   return false;
1999 }
2000
2001 /* Generate the code for argument list functions.  */
2002
2003 static void
2004 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
2005 {
2006   /* Pass by value for g77 %VAL(arg), pass the address
2007      indirectly for %LOC, else by reference.  Thus %REF
2008      is a "do-nothing" and %LOC is the same as an F95
2009      pointer.  */
2010   if (strncmp (name, "%VAL", 4) == 0)
2011     gfc_conv_expr (se, expr);
2012   else if (strncmp (name, "%LOC", 4) == 0)
2013     {
2014       gfc_conv_expr_reference (se, expr);
2015       se->expr = gfc_build_addr_expr (NULL, se->expr);
2016     }
2017   else if (strncmp (name, "%REF", 4) == 0)
2018     gfc_conv_expr_reference (se, expr);
2019   else
2020     gfc_error ("Unknown argument list function at %L", &expr->where);
2021 }
2022
2023
2024 /* Generate code for a procedure call.  Note can return se->post != NULL.
2025    If se->direct_byref is set then se->expr contains the return parameter.
2026    Return nonzero, if the call has alternate specifiers.  */
2027
2028 int
2029 gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
2030                         gfc_actual_arglist * arg, tree append_args)
2031 {
2032   gfc_interface_mapping mapping;
2033   tree arglist;
2034   tree retargs;
2035   tree tmp;
2036   tree fntype;
2037   gfc_se parmse;
2038   gfc_ss *argss;
2039   gfc_ss_info *info;
2040   int byref;
2041   int parm_kind;
2042   tree type;
2043   tree var;
2044   tree len;
2045   tree stringargs;
2046   gfc_formal_arglist *formal;
2047   int has_alternate_specifier = 0;
2048   bool need_interface_mapping;
2049   bool callee_alloc;
2050   gfc_typespec ts;
2051   gfc_charlen cl;
2052   gfc_expr *e;
2053   gfc_symbol *fsym;
2054   stmtblock_t post;
2055   enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
2056
2057   arglist = NULL_TREE;
2058   retargs = NULL_TREE;
2059   stringargs = NULL_TREE;
2060   var = NULL_TREE;
2061   len = NULL_TREE;
2062
2063   if (se->ss != NULL)
2064     {
2065       if (!sym->attr.elemental)
2066         {
2067           gcc_assert (se->ss->type == GFC_SS_FUNCTION);
2068           if (se->ss->useflags)
2069             {
2070               gcc_assert (gfc_return_by_reference (sym)
2071                       && sym->result->attr.dimension);
2072               gcc_assert (se->loop != NULL);
2073
2074               /* Access the previously obtained result.  */
2075               gfc_conv_tmp_array_ref (se);
2076               gfc_advance_se_ss_chain (se);
2077               return 0;
2078             }
2079         }
2080       info = &se->ss->data.info;
2081     }
2082   else
2083     info = NULL;
2084
2085   gfc_init_block (&post);
2086   gfc_init_interface_mapping (&mapping);
2087   need_interface_mapping = ((sym->ts.type == BT_CHARACTER
2088                                   && sym->ts.cl->length
2089                                   && sym->ts.cl->length->expr_type
2090                                                 != EXPR_CONSTANT)
2091                               || sym->attr.dimension);
2092   formal = sym->formal;
2093   /* Evaluate the arguments.  */
2094   for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
2095     {
2096       e = arg->expr;
2097       fsym = formal ? formal->sym : NULL;
2098       parm_kind = MISSING;
2099       if (e == NULL)
2100         {
2101
2102           if (se->ignore_optional)
2103             {
2104               /* Some intrinsics have already been resolved to the correct
2105                  parameters.  */
2106               continue;
2107             }
2108           else if (arg->label)
2109             {
2110               has_alternate_specifier = 1;
2111               continue;
2112             }
2113           else
2114             {
2115               /* Pass a NULL pointer for an absent arg.  */
2116               gfc_init_se (&parmse, NULL);
2117               parmse.expr = null_pointer_node;
2118               if (arg->missing_arg_type == BT_CHARACTER)
2119                 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
2120             }
2121         }
2122       else if (se->ss && se->ss->useflags)
2123         {
2124           /* An elemental function inside a scalarized loop.  */
2125           gfc_init_se (&parmse, se);
2126           gfc_conv_expr_reference (&parmse, e);
2127           parm_kind = ELEMENTAL;
2128         }
2129       else
2130         {
2131           /* A scalar or transformational function.  */
2132           gfc_init_se (&parmse, NULL);
2133           argss = gfc_walk_expr (e);
2134
2135           if (argss == gfc_ss_terminator)
2136             {
2137               if (fsym && fsym->attr.value)
2138                 {
2139                   gfc_conv_expr (&parmse, e);
2140                 }
2141               else if (arg->name && arg->name[0] == '%')
2142                 /* Argument list functions %VAL, %LOC and %REF are signalled
2143                    through arg->name.  */
2144                 conv_arglist_function (&parmse, arg->expr, arg->name);
2145               else if ((e->expr_type == EXPR_FUNCTION)
2146                           && e->symtree->n.sym->attr.pointer
2147                           && fsym && fsym->attr.target)
2148                 {
2149                   gfc_conv_expr (&parmse, e);
2150                   parmse.expr = build_fold_addr_expr (parmse.expr);
2151                 }
2152               else
2153                 {
2154                   gfc_conv_expr_reference (&parmse, e);
2155                   if (fsym && fsym->attr.pointer
2156                       && fsym->attr.flavor != FL_PROCEDURE
2157                       && e->expr_type != EXPR_NULL)
2158                     {
2159                       /* Scalar pointer dummy args require an extra level of
2160                          indirection. The null pointer already contains
2161                          this level of indirection.  */
2162                       parm_kind = SCALAR_POINTER;
2163                       parmse.expr = build_fold_addr_expr (parmse.expr);
2164                     }
2165                 }
2166             }
2167           else
2168             {
2169               /* If the procedure requires an explicit interface, the actual
2170                  argument is passed according to the corresponding formal
2171                  argument.  If the corresponding formal argument is a POINTER,
2172                  ALLOCATABLE or assumed shape, we do not use g77's calling
2173                  convention, and pass the address of the array descriptor
2174                  instead. Otherwise we use g77's calling convention.  */
2175               int f;
2176               f = (fsym != NULL)
2177                   && !(fsym->attr.pointer || fsym->attr.allocatable)
2178                   && fsym->as->type != AS_ASSUMED_SHAPE;
2179               f = f || !sym->attr.always_explicit;
2180
2181               if (e->expr_type == EXPR_VARIABLE
2182                     && is_aliased_array (e))
2183                 /* The actual argument is a component reference to an
2184                    array of derived types.  In this case, the argument
2185                    is converted to a temporary, which is passed and then
2186                    written back after the procedure call.  */
2187                 gfc_conv_aliased_arg (&parmse, e, f,
2188                         fsym ? fsym->attr.intent : INTENT_INOUT);
2189               else
2190                 gfc_conv_array_parameter (&parmse, e, argss, f);
2191
2192               /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 
2193                  allocated on entry, it must be deallocated.  */
2194               if (fsym && fsym->attr.allocatable
2195                   && fsym->attr.intent == INTENT_OUT)
2196                 {
2197                   tmp = build_fold_indirect_ref (parmse.expr);
2198                   tmp = gfc_trans_dealloc_allocated (tmp);
2199                   gfc_add_expr_to_block (&se->pre, tmp);
2200                 }
2201
2202             } 
2203         }
2204
2205       if (fsym)
2206         {
2207           if (e)
2208             {
2209               /* If an optional argument is itself an optional dummy
2210                  argument, check its presence and substitute a null
2211                  if absent.  */
2212               if (e->expr_type == EXPR_VARIABLE
2213                     && e->symtree->n.sym->attr.optional
2214                     && fsym->attr.optional)
2215                 gfc_conv_missing_dummy (&parmse, e, fsym->ts);
2216
2217               /* If an INTENT(OUT) dummy of derived type has a default
2218                  initializer, it must be (re)initialized here.  */
2219               if (fsym->attr.intent == INTENT_OUT
2220                     && fsym->ts.type == BT_DERIVED
2221                     && fsym->value)
2222                 {
2223                   gcc_assert (!fsym->attr.allocatable);
2224                   tmp = gfc_trans_assignment (e, fsym->value, false);
2225                   gfc_add_expr_to_block (&se->pre, tmp);
2226                 }
2227
2228               /* Obtain the character length of an assumed character
2229                  length procedure from the typespec.  */
2230               if (fsym->ts.type == BT_CHARACTER
2231                     && parmse.string_length == NULL_TREE
2232                     && e->ts.type == BT_PROCEDURE
2233                     && e->symtree->n.sym->ts.type == BT_CHARACTER
2234                     && e->symtree->n.sym->ts.cl->length != NULL)
2235                 {
2236                   gfc_conv_const_charlen (e->symtree->n.sym->ts.cl);
2237                   parmse.string_length
2238                         = e->symtree->n.sym->ts.cl->backend_decl;
2239                 }
2240             }
2241
2242           if (need_interface_mapping)
2243             gfc_add_interface_mapping (&mapping, fsym, &parmse);
2244         }
2245
2246       gfc_add_block_to_block (&se->pre, &parmse.pre);
2247       gfc_add_block_to_block (&post, &parmse.post);
2248
2249       /* Allocated allocatable components of derived types must be
2250          deallocated for INTENT(OUT) dummy arguments and non-variable
2251          scalars.  Non-variable arrays are dealt with in trans-array.c
2252          (gfc_conv_array_parameter).  */
2253       if (e && e->ts.type == BT_DERIVED
2254             && e->ts.derived->attr.alloc_comp
2255             && ((formal && formal->sym->attr.intent == INTENT_OUT)
2256                    ||
2257                 (e->expr_type != EXPR_VARIABLE && !e->rank)))
2258         {
2259           int parm_rank;
2260           tmp = build_fold_indirect_ref (parmse.expr);
2261           parm_rank = e->rank;
2262           switch (parm_kind)
2263             {
2264             case (ELEMENTAL):
2265             case (SCALAR):
2266               parm_rank = 0;
2267               break;
2268
2269             case (SCALAR_POINTER):
2270               tmp = build_fold_indirect_ref (tmp);
2271               break;
2272             case (ARRAY):
2273               tmp = parmse.expr;
2274               break;
2275             }
2276
2277           tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
2278           if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional)
2279             tmp = build3_v (COND_EXPR, gfc_conv_expr_present (e->symtree->n.sym),
2280                             tmp, build_empty_stmt ());
2281
2282           if (e->expr_type != EXPR_VARIABLE)
2283             /* Don't deallocate non-variables until they have been used.  */
2284             gfc_add_expr_to_block (&se->post, tmp);
2285           else 
2286             {
2287               gcc_assert (formal && formal->sym->attr.intent == INTENT_OUT);
2288               gfc_add_expr_to_block (&se->pre, tmp);
2289             }
2290         }
2291
2292       /* Character strings are passed as two parameters, a length and a
2293          pointer.  */
2294       if (parmse.string_length != NULL_TREE)
2295         stringargs = gfc_chainon_list (stringargs, parmse.string_length);
2296
2297       arglist = gfc_chainon_list (arglist, parmse.expr);
2298     }
2299   gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
2300
2301   ts = sym->ts;
2302   if (ts.type == BT_CHARACTER)
2303     {
2304       if (sym->ts.cl->length == NULL)
2305         {
2306           /* Assumed character length results are not allowed by 5.1.1.5 of the
2307              standard and are trapped in resolve.c; except in the case of SPREAD
2308              (and other intrinsics?) and dummy functions.  In the case of SPREAD,
2309              we take the character length of the first argument for the result.
2310              For dummies, we have to look through the formal argument list for
2311              this function and use the character length found there.*/
2312           if (!sym->attr.dummy)
2313             cl.backend_decl = TREE_VALUE (stringargs);
2314           else
2315             {
2316               formal = sym->ns->proc_name->formal;
2317               for (; formal; formal = formal->next)
2318                 if (strcmp (formal->sym->name, sym->name) == 0)
2319                   cl.backend_decl = formal->sym->ts.cl->backend_decl;
2320             }
2321         }
2322         else
2323         {
2324           tree tmp;
2325
2326           /* Calculate the length of the returned string.  */
2327           gfc_init_se (&parmse, NULL);
2328           if (need_interface_mapping)
2329             gfc_apply_interface_mapping (&mapping, &parmse, sym->ts.cl->length);
2330           else
2331             gfc_conv_expr (&parmse, sym->ts.cl->length);
2332           gfc_add_block_to_block (&se->pre, &parmse.pre);
2333           gfc_add_block_to_block (&se->post, &parmse.post);
2334           
2335           tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
2336           tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
2337                              build_int_cst (gfc_charlen_type_node, 0));
2338           cl.backend_decl = tmp;
2339         }
2340
2341       /* Set up a charlen structure for it.  */
2342       cl.next = NULL;
2343       cl.length = NULL;
2344       ts.cl = &cl;
2345
2346       len = cl.backend_decl;
2347     }
2348
2349   byref = gfc_return_by_reference (sym);
2350   if (byref)
2351     {
2352       if (se->direct_byref)
2353         {
2354           /* Sometimes, too much indirection can be applied; eg. for
2355              function_result = array_valued_recursive_function.  */
2356           if (TREE_TYPE (TREE_TYPE (se->expr))
2357                 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
2358                 && GFC_DESCRIPTOR_TYPE_P
2359                         (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
2360             se->expr = build_fold_indirect_ref (se->expr);
2361
2362           retargs = gfc_chainon_list (retargs, se->expr);
2363         }
2364       else if (sym->result->attr.dimension)
2365         {
2366           gcc_assert (se->loop && info);
2367
2368           /* Set the type of the array.  */
2369           tmp = gfc_typenode_for_spec (&ts);
2370           info->dimen = se->loop->dimen;
2371
2372           /* Evaluate the bounds of the result, if known.  */
2373           gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
2374
2375           /* Create a temporary to store the result.  In case the function
2376              returns a pointer, the temporary will be a shallow copy and
2377              mustn't be deallocated.  */
2378           callee_alloc = sym->attr.allocatable || sym->attr.pointer;
2379           gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
2380                                        false, !sym->attr.pointer, callee_alloc);
2381
2382           /* Pass the temporary as the first argument.  */
2383           tmp = info->descriptor;
2384           tmp = build_fold_addr_expr (tmp);
2385           retargs = gfc_chainon_list (retargs, tmp);
2386         }
2387       else if (ts.type == BT_CHARACTER)
2388         {
2389           /* Pass the string length.  */
2390           type = gfc_get_character_type (ts.kind, ts.cl);
2391           type = build_pointer_type (type);
2392
2393           /* Return an address to a char[0:len-1]* temporary for
2394              character pointers.  */
2395           if (sym->attr.pointer || sym->attr.allocatable)
2396             {
2397               /* Build char[0:len-1] * pstr.  */
2398               tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
2399                                  build_int_cst (gfc_charlen_type_node, 1));
2400               tmp = build_range_type (gfc_array_index_type,
2401                                       gfc_index_zero_node, tmp);
2402               tmp = build_array_type (gfc_character1_type_node, tmp);
2403               var = gfc_create_var (build_pointer_type (tmp), "pstr");
2404
2405               /* Provide an address expression for the function arguments.  */
2406               var = build_fold_addr_expr (var);
2407             }
2408           else
2409             var = gfc_conv_string_tmp (se, type, len);
2410
2411           retargs = gfc_chainon_list (retargs, var);
2412         }
2413       else
2414         {
2415           gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
2416
2417           type = gfc_get_complex_type (ts.kind);
2418           var = build_fold_addr_expr (gfc_create_var (type, "cmplx"));
2419           retargs = gfc_chainon_list (retargs, var);
2420         }
2421
2422       /* Add the string length to the argument list.  */
2423       if (ts.type == BT_CHARACTER)
2424         retargs = gfc_chainon_list (retargs, len);
2425     }
2426   gfc_free_interface_mapping (&mapping);
2427
2428   /* Add the return arguments.  */
2429   arglist = chainon (retargs, arglist);
2430
2431   /* Add the hidden string length parameters to the arguments.  */
2432   arglist = chainon (arglist, stringargs);
2433
2434   /* We may want to append extra arguments here.  This is used e.g. for
2435      calls to libgfortran_matmul_??, which need extra information.  */
2436   if (append_args != NULL_TREE)
2437     arglist = chainon (arglist, append_args);
2438
2439   /* Generate the actual call.  */
2440   gfc_conv_function_val (se, sym);
2441
2442   /* If there are alternate return labels, function type should be
2443      integer.  Can't modify the type in place though, since it can be shared
2444      with other functions.  For dummy arguments, the typing is done to
2445      to this result, even if it has to be repeated for each call.  */
2446   if (has_alternate_specifier
2447       && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
2448     {
2449       if (!sym->attr.dummy)
2450         {
2451           TREE_TYPE (sym->backend_decl)
2452                 = build_function_type (integer_type_node,
2453                       TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
2454           se->expr = build_fold_addr_expr (sym->backend_decl);
2455         }
2456       else
2457         TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
2458     }
2459
2460   fntype = TREE_TYPE (TREE_TYPE (se->expr));
2461   se->expr = build_call_list (TREE_TYPE (fntype), se->expr, arglist);
2462
2463   /* If we have a pointer function, but we don't want a pointer, e.g.
2464      something like
2465         x = f()
2466      where f is pointer valued, we have to dereference the result.  */
2467   if (!se->want_pointer && !byref && sym->attr.pointer)
2468     se->expr = build_fold_indirect_ref (se->expr);
2469
2470   /* f2c calling conventions require a scalar default real function to
2471      return a double precision result.  Convert this back to default
2472      real.  We only care about the cases that can happen in Fortran 77.
2473   */
2474   if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
2475       && sym->ts.kind == gfc_default_real_kind
2476       && !sym->attr.always_explicit)
2477     se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
2478
2479   /* A pure function may still have side-effects - it may modify its
2480      parameters.  */
2481   TREE_SIDE_EFFECTS (se->expr) = 1;
2482 #if 0
2483   if (!sym->attr.pure)
2484     TREE_SIDE_EFFECTS (se->expr) = 1;
2485 #endif
2486
2487   if (byref)
2488     {
2489       /* Add the function call to the pre chain.  There is no expression.  */
2490       gfc_add_expr_to_block (&se->pre, se->expr);
2491       se->expr = NULL_TREE;
2492
2493       if (!se->direct_byref)
2494         {
2495           if (sym->attr.dimension)
2496             {
2497               if (flag_bounds_check)
2498                 {
2499                   /* Check the data pointer hasn't been modified.  This would
2500                      happen in a function returning a pointer.  */
2501                   tmp = gfc_conv_descriptor_data_get (info->descriptor);
2502                   tmp = fold_build2 (NE_EXPR, boolean_type_node,
2503                                      tmp, info->data);
2504                   gfc_trans_runtime_check (tmp, gfc_msg_fault, &se->pre, NULL);
2505                 }
2506               se->expr = info->descriptor;
2507               /* Bundle in the string length.  */
2508               se->string_length = len;
2509             }
2510           else if (sym->ts.type == BT_CHARACTER)
2511             {
2512               /* Dereference for character pointer results.  */
2513               if (sym->attr.pointer || sym->attr.allocatable)
2514                 se->expr = build_fold_indirect_ref (var);
2515               else
2516                 se->expr = var;
2517
2518               se->string_length = len;
2519             }
2520           else
2521             {
2522               gcc_assert (sym->ts.type == BT_COMPLEX && gfc_option.flag_f2c);
2523               se->expr = build_fold_indirect_ref (var);
2524             }
2525         }
2526     }
2527
2528   /* Follow the function call with the argument post block.  */
2529   if (byref)
2530     gfc_add_block_to_block (&se->pre, &post);
2531   else
2532     gfc_add_block_to_block (&se->post, &post);
2533
2534   return has_alternate_specifier;
2535 }
2536
2537
2538 /* Generate code to copy a string.  */
2539
2540 static void
2541 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
2542                        tree slength, tree src)
2543 {
2544   tree tmp, dlen, slen;
2545   tree dsc;
2546   tree ssc;
2547   tree cond;
2548   tree cond2;
2549   tree tmp2;
2550   tree tmp3;
2551   tree tmp4;
2552   stmtblock_t tempblock;
2553
2554   dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
2555   slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
2556
2557   /* Deal with single character specially.  */
2558   dsc = gfc_to_single_character (dlen, dest);
2559   ssc = gfc_to_single_character (slen, src);
2560   if (dsc != NULL_TREE && ssc != NULL_TREE)
2561     {
2562       gfc_add_modify_expr (block, dsc, ssc);
2563       return;
2564     }
2565
2566   /* Do nothing if the destination length is zero.  */
2567   cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
2568                       build_int_cst (size_type_node, 0));
2569
2570   /* The following code was previously in _gfortran_copy_string:
2571
2572        // The two strings may overlap so we use memmove.
2573        void
2574        copy_string (GFC_INTEGER_4 destlen, char * dest,
2575                     GFC_INTEGER_4 srclen, const char * src)
2576        {
2577          if (srclen >= destlen)
2578            {
2579              // This will truncate if too long.
2580              memmove (dest, src, destlen);
2581            }
2582          else
2583            {
2584              memmove (dest, src, srclen);
2585              // Pad with spaces.
2586              memset (&dest[srclen], ' ', destlen - srclen);
2587            }
2588        }
2589
2590      We're now doing it here for better optimization, but the logic
2591      is the same.  */
2592   
2593   /* Truncate string if source is too long.  */
2594   cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
2595   tmp2 = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE],
2596                           3, dest, src, dlen);
2597
2598   /* Else copy and pad with spaces.  */
2599   tmp3 = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE],
2600                           3, dest, src, slen);
2601
2602   tmp4 = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, dest,
2603                       fold_convert (sizetype, slen));
2604   tmp4 = build_call_expr (built_in_decls[BUILT_IN_MEMSET], 3,
2605                           tmp4, 
2606                           build_int_cst (gfc_get_int_type (gfc_c_int_kind),
2607                                          lang_hooks.to_target_charset (' ')),
2608                           fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
2609                                        dlen, slen));
2610
2611   gfc_init_block (&tempblock);
2612   gfc_add_expr_to_block (&tempblock, tmp3);
2613   gfc_add_expr_to_block (&tempblock, tmp4);
2614   tmp3 = gfc_finish_block (&tempblock);
2615
2616   /* The whole copy_string function is there.  */
2617   tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
2618   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
2619   gfc_add_expr_to_block (block, tmp);
2620 }
2621
2622
2623 /* Translate a statement function.
2624    The value of a statement function reference is obtained by evaluating the
2625    expression using the values of the actual arguments for the values of the
2626    corresponding dummy arguments.  */
2627
2628 static void
2629 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
2630 {
2631   gfc_symbol *sym;
2632   gfc_symbol *fsym;
2633   gfc_formal_arglist *fargs;
2634   gfc_actual_arglist *args;
2635   gfc_se lse;
2636   gfc_se rse;
2637   gfc_saved_var *saved_vars;
2638   tree *temp_vars;
2639   tree type;
2640   tree tmp;
2641   int n;
2642
2643   sym = expr->symtree->n.sym;
2644   args = expr->value.function.actual;
2645   gfc_init_se (&lse, NULL);
2646   gfc_init_se (&rse, NULL);
2647
2648   n = 0;
2649   for (fargs = sym->formal; fargs; fargs = fargs->next)
2650     n++;
2651   saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
2652   temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
2653
2654   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2655     {
2656       /* Each dummy shall be specified, explicitly or implicitly, to be
2657          scalar.  */
2658       gcc_assert (fargs->sym->attr.dimension == 0);
2659       fsym = fargs->sym;
2660
2661       /* Create a temporary to hold the value.  */
2662       type = gfc_typenode_for_spec (&fsym->ts);
2663       temp_vars[n] = gfc_create_var (type, fsym->name);
2664
2665       if (fsym->ts.type == BT_CHARACTER)
2666         {
2667           /* Copy string arguments.  */
2668           tree arglen;
2669
2670           gcc_assert (fsym->ts.cl && fsym->ts.cl->length
2671                   && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
2672
2673           arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2674           tmp = gfc_build_addr_expr (build_pointer_type (type),
2675                                      temp_vars[n]);
2676
2677           gfc_conv_expr (&rse, args->expr);
2678           gfc_conv_string_parameter (&rse);
2679           gfc_add_block_to_block (&se->pre, &lse.pre);
2680           gfc_add_block_to_block (&se->pre, &rse.pre);
2681
2682           gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
2683                                  rse.expr);
2684           gfc_add_block_to_block (&se->pre, &lse.post);
2685           gfc_add_block_to_block (&se->pre, &rse.post);
2686         }
2687       else
2688         {
2689           /* For everything else, just evaluate the expression.  */
2690           gfc_conv_expr (&lse, args->expr);
2691
2692           gfc_add_block_to_block (&se->pre, &lse.pre);
2693           gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
2694           gfc_add_block_to_block (&se->pre, &lse.post);
2695         }
2696
2697       args = args->next;
2698     }
2699
2700   /* Use the temporary variables in place of the real ones.  */
2701   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2702     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
2703
2704   gfc_conv_expr (se, sym->value);
2705
2706   if (sym->ts.type == BT_CHARACTER)
2707     {
2708       gfc_conv_const_charlen (sym->ts.cl);
2709
2710       /* Force the expression to the correct length.  */
2711       if (!INTEGER_CST_P (se->string_length)
2712           || tree_int_cst_lt (se->string_length,
2713                               sym->ts.cl->backend_decl))
2714         {
2715           type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
2716           tmp = gfc_create_var (type, sym->name);
2717           tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
2718           gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
2719                                  se->string_length, se->expr);
2720           se->expr = tmp;
2721         }
2722       se->string_length = sym->ts.cl->backend_decl;
2723     }
2724
2725   /* Restore the original variables.  */
2726   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2727     gfc_restore_sym (fargs->sym, &saved_vars[n]);
2728   gfc_free (saved_vars);
2729 }
2730
2731
2732 /* Translate a function expression.  */
2733
2734 static void
2735 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
2736 {
2737   gfc_symbol *sym;
2738
2739   if (expr->value.function.isym)
2740     {
2741       gfc_conv_intrinsic_function (se, expr);
2742       return;
2743     }
2744
2745   /* We distinguish statement functions from general functions to improve
2746      runtime performance.  */
2747   if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
2748     {
2749       gfc_conv_statement_function (se, expr);
2750       return;
2751     }
2752
2753   /* expr.value.function.esym is the resolved (specific) function symbol for
2754      most functions.  However this isn't set for dummy procedures.  */
2755   sym = expr->value.function.esym;
2756   if (!sym)
2757     sym = expr->symtree->n.sym;
2758   gfc_conv_function_call (se, sym, expr->value.function.actual, NULL_TREE);
2759 }
2760
2761
2762 static void
2763 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
2764 {
2765   gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
2766   gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
2767
2768   gfc_conv_tmp_array_ref (se);
2769   gfc_advance_se_ss_chain (se);
2770 }
2771
2772
2773 /* Build a static initializer.  EXPR is the expression for the initial value.
2774    The other parameters describe the variable of the component being 
2775    initialized. EXPR may be null.  */
2776
2777 tree
2778 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
2779                       bool array, bool pointer)
2780 {
2781   gfc_se se;
2782
2783   if (!(expr || pointer))
2784     return NULL_TREE;
2785
2786   if (expr != NULL && expr->ts.type == BT_DERIVED
2787       && expr->ts.is_iso_c && expr->ts.derived
2788       && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
2789           || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR))
2790       expr = gfc_int_expr (0);
2791   
2792   if (array)
2793     {
2794       /* Arrays need special handling.  */
2795       if (pointer)
2796         return gfc_build_null_descriptor (type);
2797       else
2798         return gfc_conv_array_initializer (type, expr);
2799     }
2800   else if (pointer)
2801     return fold_convert (type, null_pointer_node);
2802   else
2803     {
2804       switch (ts->type)
2805         {
2806         case BT_DERIVED:
2807           gfc_init_se (&se, NULL);
2808           gfc_conv_structure (&se, expr, 1);
2809           return se.expr;
2810
2811         case BT_CHARACTER:
2812           return gfc_conv_string_init (ts->cl->backend_decl,expr);
2813
2814         default:
2815           gfc_init_se (&se, NULL);
2816           gfc_conv_constant (&se, expr);
2817           return se.expr;
2818         }
2819     }
2820 }
2821   
2822 static tree
2823 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2824 {
2825   gfc_se rse;
2826   gfc_se lse;
2827   gfc_ss *rss;
2828   gfc_ss *lss;
2829   stmtblock_t body;
2830   stmtblock_t block;
2831   gfc_loopinfo loop;
2832   int n;
2833   tree tmp;
2834
2835   gfc_start_block (&block);
2836
2837   /* Initialize the scalarizer.  */
2838   gfc_init_loopinfo (&loop);
2839
2840   gfc_init_se (&lse, NULL);
2841   gfc_init_se (&rse, NULL);
2842
2843   /* Walk the rhs.  */
2844   rss = gfc_walk_expr (expr);
2845   if (rss == gfc_ss_terminator)
2846     {
2847       /* The rhs is scalar.  Add a ss for the expression.  */
2848       rss = gfc_get_ss ();
2849       rss->next = gfc_ss_terminator;
2850       rss->type = GFC_SS_SCALAR;
2851       rss->expr = expr;
2852     }
2853
2854   /* Create a SS for the destination.  */
2855   lss = gfc_get_ss ();
2856   lss->type = GFC_SS_COMPONENT;
2857   lss->expr = NULL;
2858   lss->shape = gfc_get_shape (cm->as->rank);
2859   lss->next = gfc_ss_terminator;
2860   lss->data.info.dimen = cm->as->rank;
2861   lss->data.info.descriptor = dest;
2862   lss->data.info.data = gfc_conv_array_data (dest);
2863   lss->data.info.offset = gfc_conv_array_offset (dest);
2864   for (n = 0; n < cm->as->rank; n++)
2865     {
2866       lss->data.info.dim[n] = n;
2867       lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
2868       lss->data.info.stride[n] = gfc_index_one_node;
2869
2870       mpz_init (lss->shape[n]);
2871       mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
2872                cm->as->lower[n]->value.integer);
2873       mpz_add_ui (lss->shape[n], lss->shape[n], 1);
2874     }
2875   
2876   /* Associate the SS with the loop.  */
2877   gfc_add_ss_to_loop (&loop, lss);
2878   gfc_add_ss_to_loop (&loop, rss);
2879
2880   /* Calculate the bounds of the scalarization.  */
2881   gfc_conv_ss_startstride (&loop);
2882
2883   /* Setup the scalarizing loops.  */
2884   gfc_conv_loop_setup (&loop);
2885
2886   /* Setup the gfc_se structures.  */
2887   gfc_copy_loopinfo_to_se (&lse, &loop);
2888   gfc_copy_loopinfo_to_se (&rse, &loop);
2889
2890   rse.ss = rss;
2891   gfc_mark_ss_chain_used (rss, 1);
2892   lse.ss = lss;
2893   gfc_mark_ss_chain_used (lss, 1);
2894
2895   /* Start the scalarized loop body.  */
2896   gfc_start_scalarized_body (&loop, &body);
2897
2898   gfc_conv_tmp_array_ref (&lse);
2899   if (cm->ts.type == BT_CHARACTER)
2900     lse.string_length = cm->ts.cl->backend_decl;
2901
2902   gfc_conv_expr (&rse, expr);
2903
2904   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
2905   gfc_add_expr_to_block (&body, tmp);
2906
2907   gcc_assert (rse.ss == gfc_ss_terminator);
2908
2909   /* Generate the copying loops.  */
2910   gfc_trans_scalarizing_loops (&loop, &body);
2911
2912   /* Wrap the whole thing up.  */
2913   gfc_add_block_to_block (&block, &loop.pre);
2914   gfc_add_block_to_block (&block, &loop.post);
2915
2916   for (n = 0; n < cm->as->rank; n++)
2917     mpz_clear (lss->shape[n]);
2918   gfc_free (lss->shape);
2919
2920   gfc_cleanup_loop (&loop);
2921
2922   return gfc_finish_block (&block);
2923 }
2924
2925
2926 /* Assign a single component of a derived type constructor.  */
2927
2928 static tree
2929 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2930 {
2931   gfc_se se;
2932   gfc_se lse;
2933   gfc_ss *rss;
2934   stmtblock_t block;
2935   tree tmp;
2936   tree offset;
2937   int n;
2938
2939   gfc_start_block (&block);
2940
2941   if (cm->pointer)
2942     {
2943       gfc_init_se (&se, NULL);
2944       /* Pointer component.  */
2945       if (cm->dimension)
2946         {
2947           /* Array pointer.  */
2948           if (expr->expr_type == EXPR_NULL)
2949             gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
2950           else
2951             {
2952               rss = gfc_walk_expr (expr);
2953               se.direct_byref = 1;
2954               se.expr = dest;
2955               gfc_conv_expr_descriptor (&se, expr, rss);
2956               gfc_add_block_to_block (&block, &se.pre);
2957               gfc_add_block_to_block (&block, &se.post);
2958             }
2959         }
2960       else
2961         {
2962           /* Scalar pointers.  */
2963           se.want_pointer = 1;
2964           gfc_conv_expr (&se, expr);
2965           gfc_add_block_to_block (&block, &se.pre);
2966           gfc_add_modify_expr (&block, dest,
2967                                fold_convert (TREE_TYPE (dest), se.expr));
2968           gfc_add_block_to_block (&block, &se.post);
2969         }
2970     }
2971   else if (cm->dimension)
2972     {
2973       if (cm->allocatable && expr->expr_type == EXPR_NULL)
2974         gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
2975       else if (cm->allocatable)
2976         {
2977           tree tmp2;
2978
2979           gfc_init_se (&se, NULL);
2980  
2981           rss = gfc_walk_expr (expr);
2982           se.want_pointer = 0;
2983           gfc_conv_expr_descriptor (&se, expr, rss);
2984           gfc_add_block_to_block (&block, &se.pre);
2985
2986           tmp = fold_convert (TREE_TYPE (dest), se.expr);
2987           gfc_add_modify_expr (&block, dest, tmp);
2988
2989           if (cm->ts.type == BT_DERIVED && cm->ts.derived->attr.alloc_comp)
2990             tmp = gfc_copy_alloc_comp (cm->ts.derived, se.expr, dest,
2991                                        cm->as->rank);
2992           else
2993             tmp = gfc_duplicate_allocatable (dest, se.expr,
2994                                              TREE_TYPE(cm->backend_decl),
2995                                              cm->as->rank);
2996
2997           gfc_add_expr_to_block (&block, tmp);
2998
2999           gfc_add_block_to_block (&block, &se.post);
3000           gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
3001
3002           /* Shift the lbound and ubound of temporaries to being unity, rather
3003              than zero, based.  Calculate the offset for all cases.  */
3004           offset = gfc_conv_descriptor_offset (dest);
3005           gfc_add_modify_expr (&block, offset, gfc_index_zero_node);
3006           tmp2 =gfc_create_var (gfc_array_index_type, NULL);
3007           for (n = 0; n < expr->rank; n++)
3008             {
3009               if (expr->expr_type != EXPR_VARIABLE
3010                     && expr->expr_type != EXPR_CONSTANT)
3011                 {
3012                   tree span;
3013                   tmp = gfc_conv_descriptor_ubound (dest, gfc_rank_cst[n]);
3014                   span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
3015                             gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]));
3016                   gfc_add_modify_expr (&block, tmp,
3017                                        fold_build2 (PLUS_EXPR,
3018                                                     gfc_array_index_type,
3019                                                     span, gfc_index_one_node));
3020                   tmp = gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]);
3021                   gfc_add_modify_expr (&block, tmp, gfc_index_one_node);
3022                 }
3023               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3024                                  gfc_conv_descriptor_lbound (dest,
3025                                                              gfc_rank_cst[n]),
3026                                  gfc_conv_descriptor_stride (dest,
3027                                                              gfc_rank_cst[n]));
3028               gfc_add_modify_expr (&block, tmp2, tmp);
3029               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
3030               gfc_add_modify_expr (&block, offset, tmp);
3031             }
3032         }
3033       else
3034         {
3035           tmp = gfc_trans_subarray_assign (dest, cm, expr);
3036           gfc_add_expr_to_block (&block, tmp);
3037         }
3038     }
3039   else if (expr->ts.type == BT_DERIVED)
3040     {
3041       if (expr->expr_type != EXPR_STRUCTURE)
3042         {
3043           gfc_init_se (&se, NULL);
3044           gfc_conv_expr (&se, expr);
3045           gfc_add_modify_expr (&block, dest,
3046                                fold_convert (TREE_TYPE (dest), se.expr));
3047         }
3048       else
3049         {
3050           /* Nested constructors.  */
3051           tmp = gfc_trans_structure_assign (dest, expr);
3052           gfc_add_expr_to_block (&block, tmp);
3053         }
3054     }
3055   else
3056     {
3057       /* Scalar component.  */
3058       gfc_init_se (&se, NULL);
3059       gfc_init_se (&lse, NULL);
3060
3061       gfc_conv_expr (&se, expr);
3062       if (cm->ts.type == BT_CHARACTER)
3063         lse.string_length = cm->ts.cl->backend_decl;
3064       lse.expr = dest;
3065       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
3066       gfc_add_expr_to_block (&block, tmp);
3067     }
3068   return gfc_finish_block (&block);
3069 }
3070
3071 /* Assign a derived type constructor to a variable.  */
3072
3073 static tree
3074 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
3075 {
3076   gfc_constructor *c;
3077   gfc_component *cm;
3078   stmtblock_t block;
3079   tree field;
3080   tree tmp;
3081
3082   gfc_start_block (&block);
3083   cm = expr->ts.derived->components;
3084   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
3085     {
3086       /* Skip absent members in default initializers.  */
3087       if (!c->expr)
3088         continue;
3089
3090       field = cm->backend_decl;
3091       tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
3092       tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
3093       gfc_add_expr_to_block (&block, tmp);
3094     }
3095   return gfc_finish_block (&block);
3096 }
3097
3098 /* Build an expression for a constructor. If init is nonzero then
3099    this is part of a static variable initializer.  */
3100
3101 void
3102 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
3103 {
3104   gfc_constructor *c;
3105   gfc_component *cm;
3106   tree val;
3107   tree type;
3108   tree tmp;
3109   VEC(constructor_elt,gc) *v = NULL;
3110
3111   gcc_assert (se->ss == NULL);
3112   gcc_assert (expr->expr_type == EXPR_STRUCTURE);
3113   type = gfc_typenode_for_spec (&expr->ts);
3114
3115   if (!init)
3116     {
3117       /* Create a temporary variable and fill it in.  */
3118       se->expr = gfc_create_var (type, expr->ts.derived->name);
3119       tmp = gfc_trans_structure_assign (se->expr, expr);
3120       gfc_add_expr_to_block (&se->pre, tmp);
3121       return;
3122     }
3123
3124   cm = expr->ts.derived->components;
3125
3126   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
3127     {
3128       /* Skip absent members in default initializers and allocatable
3129          components.  Although the latter have a default initializer
3130          of EXPR_NULL,... by default, the static nullify is not needed
3131          since this is done every time we come into scope.  */
3132       if (!c->expr || cm->allocatable)
3133         continue;
3134
3135       val = gfc_conv_initializer (c->expr, &cm->ts,
3136           TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
3137
3138       /* Append it to the constructor list.  */
3139       CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
3140     }
3141   se->expr = build_constructor (type, v);
3142 }
3143
3144
3145 /* Translate a substring expression.  */
3146
3147 static void
3148 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
3149 {
3150   gfc_ref *ref;
3151
3152   ref = expr->ref;
3153
3154   gcc_assert (ref->type == REF_SUBSTRING);
3155
3156   se->expr = gfc_build_string_const(expr->value.character.length,
3157                                     expr->value.character.string);
3158   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
3159   TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
3160
3161   gfc_conv_substring(se,ref,expr->ts.kind,NULL,&expr->where);
3162 }
3163
3164
3165 /* Entry point for expression translation.  Evaluates a scalar quantity.
3166    EXPR is the expression to be translated, and SE is the state structure if
3167    called from within the scalarized.  */
3168
3169 void
3170 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
3171 {
3172   if (se->ss && se->ss->expr == expr
3173       && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
3174     {
3175       /* Substitute a scalar expression evaluated outside the scalarization
3176          loop.  */
3177       se->expr = se->ss->data.scalar.expr;
3178       se->string_length = se->ss->string_length;
3179       gfc_advance_se_ss_chain (se);
3180       return;
3181     }
3182
3183   /* We need to convert the expressions for the iso_c_binding derived types.
3184      C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
3185      null_pointer_node.  C_PTR and C_FUNPTR are converted to match the
3186      typespec for the C_PTR and C_FUNPTR symbols, which has already been
3187      updated to be an integer with a kind equal to the size of a (void *).  */
3188   if (expr->ts.type == BT_DERIVED && expr->ts.derived
3189       && expr->ts.derived->attr.is_iso_c)
3190     {
3191       if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
3192           || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
3193         {
3194           /* Set expr_type to EXPR_NULL, which will result in
3195              null_pointer_node being used below.  */
3196           expr->expr_type = EXPR_NULL;
3197         }
3198       else
3199         {
3200           /* Update the type/kind of the expression to be what the new
3201              type/kind are for the updated symbols of C_PTR/C_FUNPTR.  */
3202           expr->ts.type = expr->ts.derived->ts.type;
3203           expr->ts.f90_type = expr->ts.derived->ts.f90_type;
3204           expr->ts.kind = expr->ts.derived->ts.kind;
3205         }
3206     }
3207   
3208   switch (expr->expr_type)
3209     {
3210     case EXPR_OP:
3211       gfc_conv_expr_op (se, expr);
3212       break;
3213
3214     case EXPR_FUNCTION:
3215       gfc_conv_function_expr (se, expr);
3216       break;
3217
3218     case EXPR_CONSTANT:
3219       gfc_conv_constant (se, expr);
3220       break;
3221
3222     case EXPR_VARIABLE:
3223       gfc_conv_variable (se, expr);
3224       break;
3225
3226     case EXPR_NULL:
3227       se->expr = null_pointer_node;
3228       break;
3229
3230     case EXPR_SUBSTRING:
3231       gfc_conv_substring_expr (se, expr);
3232       break;
3233
3234     case EXPR_STRUCTURE:
3235       gfc_conv_structure (se, expr, 0);
3236       break;
3237
3238     case EXPR_ARRAY:
3239       gfc_conv_array_constructor_expr (se, expr);
3240       break;
3241
3242     default:
3243       gcc_unreachable ();
3244       break;
3245     }
3246 }
3247
3248 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
3249    of an assignment.  */
3250 void
3251 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
3252 {
3253   gfc_conv_expr (se, expr);
3254   /* All numeric lvalues should have empty post chains.  If not we need to
3255      figure out a way of rewriting an lvalue so that it has no post chain.  */
3256   gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
3257 }
3258
3259 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
3260    numeric expressions.  Used for scalar values where inserting cleanup code
3261    is inconvenient.  */
3262 void
3263 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
3264 {
3265   tree val;
3266
3267   gcc_assert (expr->ts.type != BT_CHARACTER);
3268   gfc_conv_expr (se, expr);
3269   if (se->post.head)
3270     {
3271       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
3272       gfc_add_modify_expr (&se->pre, val, se->expr);
3273       se->expr = val;
3274       gfc_add_block_to_block (&se->pre, &se->post);
3275     }
3276 }
3277
3278 /* Helper to translate and expression and convert it to a particular type.  */
3279 void
3280 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
3281 {
3282   gfc_conv_expr_val (se, expr);
3283   se->expr = convert (type, se->expr);
3284 }
3285
3286
3287 /* Converts an expression so that it can be passed by reference.  Scalar
3288    values only.  */
3289
3290 void
3291 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
3292 {
3293   tree var;
3294
3295   if (se->ss && se->ss->expr == expr
3296       && se->ss->type == GFC_SS_REFERENCE)
3297     {
3298       se->expr = se->ss->data.scalar.expr;
3299       se->string_length = se->ss->string_length;
3300       gfc_advance_se_ss_chain (se);
3301       return;
3302     }
3303
3304   if (expr->ts.type == BT_CHARACTER)
3305     {
3306       gfc_conv_expr (se, expr);
3307       gfc_conv_string_parameter (se);
3308       return;
3309     }
3310
3311   if (expr->expr_type == EXPR_VARIABLE)
3312     {
3313       se->want_pointer = 1;
3314       gfc_conv_expr (se, expr);
3315       if (se->post.head)
3316         {
3317           var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3318           gfc_add_modify_expr (&se->pre, var, se->expr);
3319           gfc_add_block_to_block (&se->pre, &se->post);
3320           se->expr = var;
3321         }
3322       return;
3323     }
3324
3325   gfc_conv_expr (se, expr);
3326
3327   /* Create a temporary var to hold the value.  */
3328   if (TREE_CONSTANT (se->expr))
3329     {
3330       tree tmp = se->expr;
3331       STRIP_TYPE_NOPS (tmp);
3332       var = build_decl (CONST_DECL, NULL, TREE_TYPE (tmp));
3333       DECL_INITIAL (var) = tmp;
3334       TREE_STATIC (var) = 1;
3335       pushdecl (var);
3336     }
3337   else
3338     {
3339       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3340       gfc_add_modify_expr (&se->pre, var, se->expr);
3341     }
3342   gfc_add_block_to_block (&se->pre, &se->post);
3343
3344   /* Take the address of that value.  */
3345   se->expr = build_fold_addr_expr (var);
3346 }
3347
3348
3349 tree
3350 gfc_trans_pointer_assign (gfc_code * code)
3351 {
3352   return gfc_trans_pointer_assignment (code->expr, code->expr2);
3353 }
3354
3355
3356 /* Generate code for a pointer assignment.  */
3357
3358 tree
3359 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
3360 {
3361   gfc_se lse;
3362   gfc_se rse;
3363   gfc_ss *lss;
3364   gfc_ss *rss;
3365   stmtblock_t block;
3366   tree desc;
3367   tree tmp;
3368
3369   gfc_start_block (&block);
3370
3371   gfc_init_se (&lse, NULL);
3372
3373   lss = gfc_walk_expr (expr1);
3374   rss = gfc_walk_expr (expr2);
3375   if (lss == gfc_ss_terminator)
3376     {
3377       /* Scalar pointers.  */
3378       lse.want_pointer = 1;
3379       gfc_conv_expr (&lse, expr1);
3380       gcc_assert (rss == gfc_ss_terminator);
3381       gfc_init_se (&rse, NULL);
3382       rse.want_pointer = 1;
3383       gfc_conv_expr (&rse, expr2);
3384       gfc_add_block_to_block (&block, &lse.pre);
3385       gfc_add_block_to_block (&block, &rse.pre);
3386       gfc_add_modify_expr (&block, lse.expr,
3387                            fold_convert (TREE_TYPE (lse.expr), rse.expr));
3388       gfc_add_block_to_block (&block, &rse.post);
3389       gfc_add_block_to_block (&block, &lse.post);
3390     }
3391   else
3392     {
3393       /* Array pointer.  */
3394       gfc_conv_expr_descriptor (&lse, expr1, lss);
3395       switch (expr2->expr_type)
3396         {
3397         case EXPR_NULL:
3398           /* Just set the data pointer to null.  */
3399           gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
3400           break;
3401
3402         case EXPR_VARIABLE:
3403           /* Assign directly to the pointer's descriptor.  */
3404           lse.direct_byref = 1;
3405           gfc_conv_expr_descriptor (&lse, expr2, rss);
3406           break;
3407
3408         default:
3409           /* Assign to a temporary descriptor and then copy that
3410              temporary to the pointer.  */
3411           desc = lse.expr;
3412           tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
3413
3414           lse.expr = tmp;
3415           lse.direct_byref = 1;
3416           gfc_conv_expr_descriptor (&lse, expr2, rss);
3417           gfc_add_modify_expr (&lse.pre, desc, tmp);
3418           break;
3419         }
3420       gfc_add_block_to_block (&block, &lse.pre);
3421       gfc_add_block_to_block (&block, &lse.post);
3422     }
3423   return gfc_finish_block (&block);
3424 }
3425
3426
3427 /* Makes sure se is suitable for passing as a function string parameter.  */
3428 /* TODO: Need to check all callers fo this function.  It may be abused.  */
3429
3430 void
3431 gfc_conv_string_parameter (gfc_se * se)
3432 {
3433   tree type;
3434
3435   if (TREE_CODE (se->expr) == STRING_CST)
3436     {
3437       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3438       return;
3439     }
3440
3441   type = TREE_TYPE (se->expr);
3442   if (TYPE_STRING_FLAG (type))
3443     {
3444       gcc_assert (TREE_CODE (se->expr) != INDIRECT_REF);
3445       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3446     }
3447
3448   gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
3449   gcc_assert (se->string_length
3450           && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
3451 }
3452
3453
3454 /* Generate code for assignment of scalar variables.  Includes character
3455    strings and derived types with allocatable components.  */
3456
3457 tree
3458 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
3459                          bool l_is_temp, bool r_is_var)
3460 {
3461   stmtblock_t block;
3462   tree tmp;
3463   tree cond;
3464
3465   gfc_init_block (&block);
3466
3467   if (ts.type == BT_CHARACTER)
3468     {
3469       gcc_assert (lse->string_length != NULL_TREE
3470               && rse->string_length != NULL_TREE);
3471
3472       gfc_conv_string_parameter (lse);
3473       gfc_conv_string_parameter (rse);
3474
3475       gfc_add_block_to_block (&block, &lse->pre);
3476       gfc_add_block_to_block (&block, &rse->pre);
3477
3478       gfc_trans_string_copy (&block, lse->string_length, lse->expr,
3479                              rse->string_length, rse->expr);
3480     }
3481   else if (ts.type == BT_DERIVED && ts.derived->attr.alloc_comp)
3482     {
3483       cond = NULL_TREE;
3484         
3485       /* Are the rhs and the lhs the same?  */
3486       if (r_is_var)
3487         {
3488           cond = fold_build2 (EQ_EXPR, boolean_type_node,
3489                               build_fold_addr_expr (lse->expr),
3490                               build_fold_addr_expr (rse->expr));
3491           cond = gfc_evaluate_now (cond, &lse->pre);
3492         }
3493
3494       /* Deallocate the lhs allocated components as long as it is not
3495          the same as the rhs.  */
3496       if (!l_is_temp)
3497         {
3498           tmp = gfc_deallocate_alloc_comp (ts.derived, lse->expr, 0);
3499           if (r_is_var)
3500             tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3501           gfc_add_expr_to_block (&lse->pre, tmp);
3502         }
3503
3504       if (r_is_var)
3505         {
3506           gfc_add_block_to_block (&block, &lse->pre);
3507           gfc_add_block_to_block (&block, &rse->pre);
3508         }
3509       else
3510         {
3511           gfc_add_block_to_block (&block, &rse->pre);
3512           gfc_add_block_to_block (&block, &lse->pre);
3513         }
3514
3515       gfc_add_modify_expr (&block, lse->expr,
3516                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
3517
3518       /* Do a deep copy if the rhs is a variable, if it is not the
3519          same as the lhs.  */
3520       if (r_is_var)
3521         {
3522           tmp = gfc_copy_alloc_comp (ts.derived, rse->expr, lse->expr, 0);
3523           tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3524           gfc_add_expr_to_block (&block, tmp);
3525         }
3526     }
3527   else
3528     {
3529       gfc_add_block_to_block (&block, &lse->pre);
3530       gfc_add_block_to_block (&block, &rse->pre);
3531
3532       gfc_add_modify_expr (&block, lse->expr,
3533                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
3534     }
3535
3536   gfc_add_block_to_block (&block, &lse->post);
3537   gfc_add_block_to_block (&block, &rse->post);
3538
3539   return gfc_finish_block (&block);
3540 }
3541
3542
3543 /* Try to translate array(:) = func (...), where func is a transformational
3544    array function, without using a temporary.  Returns NULL is this isn't the
3545    case.  */
3546
3547 static tree
3548 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
3549 {
3550   gfc_se se;
3551   gfc_ss *ss;
3552   gfc_ref * ref;
3553   bool seen_array_ref;
3554
3555   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
3556   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
3557     return NULL;
3558
3559   /* Elemental functions don't need a temporary anyway.  */
3560   if (expr2->value.function.esym != NULL
3561       && expr2->value.function.esym->attr.elemental)
3562     return NULL;
3563
3564   /* Fail if EXPR1 can't be expressed as a descriptor.  */
3565   if (gfc_ref_needs_temporary_p (expr1->ref))
3566     return NULL;
3567
3568   /* Functions returning pointers need temporaries.  */
3569   if (expr2->symtree->n.sym->attr.pointer 
3570       || expr2->symtree->n.sym->attr.allocatable)
3571     return NULL;
3572
3573   /* Character array functions need temporaries unless the
3574      character lengths are the same.  */
3575   if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
3576     {
3577       if (expr1->ts.cl->length == NULL
3578             || expr1->ts.cl->length->expr_type != EXPR_CONSTANT)
3579         return NULL;
3580
3581       if (expr2->ts.cl->length == NULL
3582             || expr2->ts.cl->length->expr_type != EXPR_CONSTANT)
3583         return NULL;
3584
3585       if (mpz_cmp (expr1->ts.cl->length->value.integer,
3586                      expr2->ts.cl->length->value.integer) != 0)
3587         return NULL;
3588     }
3589
3590   /* Check that no LHS component references appear during an array
3591      reference. This is needed because we do not have the means to
3592      span any arbitrary stride with an array descriptor. This check
3593      is not needed for the rhs because the function result has to be
3594      a complete type.  */
3595   seen_array_ref = false;
3596   for (ref = expr1->ref; ref; ref = ref->next)
3597     {
3598       if (ref->type == REF_ARRAY)
3599         seen_array_ref= true;
3600       else if (ref->type == REF_COMPONENT && seen_array_ref)
3601         return NULL;
3602     }
3603
3604   /* Check for a dependency.  */
3605   if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
3606                                    expr2->value.function.esym,
3607                                    expr2->value.function.actual))
3608     return NULL;
3609
3610   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
3611      functions.  */
3612   gcc_assert (expr2->value.function.isym
3613               || (gfc_return_by_reference (expr2->value.function.esym)
3614               && expr2->value.function.esym->result->attr.dimension));
3615
3616   ss = gfc_walk_expr (expr1);
3617   gcc_assert (ss != gfc_ss_terminator);
3618   gfc_init_se (&se, NULL);
3619   gfc_start_block (&se.pre);
3620   se.want_pointer = 1;
3621
3622   gfc_conv_array_parameter (&se, expr1, ss, 0);
3623
3624   se.direct_byref = 1;
3625   se.ss = gfc_walk_expr (expr2);
3626   gcc_assert (se.ss != gfc_ss_terminator);
3627   gfc_conv_function_expr (&se, expr2);
3628   gfc_add_block_to_block (&se.pre, &se.post);
3629
3630   return gfc_finish_block (&se.pre);
3631 }
3632
3633 /* Determine whether the given EXPR_CONSTANT is a zero initializer.  */
3634
3635 static bool
3636 is_zero_initializer_p (gfc_expr * expr)
3637 {
3638   if (expr->expr_type != EXPR_CONSTANT)
3639     return false;
3640
3641   /* We ignore constants with prescribed memory representations for now.  */
3642   if (expr->representation.string)
3643     return false;
3644
3645   switch (expr->ts.type)
3646     {
3647     case BT_INTEGER:
3648       return mpz_cmp_si (expr->value.integer, 0) == 0;
3649
3650     case BT_REAL:
3651       return mpfr_zero_p (expr->value.real)
3652              && MPFR_SIGN (expr->value.real) >= 0;
3653
3654     case BT_LOGICAL:
3655       return expr->value.logical == 0;
3656
3657     case BT_COMPLEX:
3658       return mpfr_zero_p (expr->value.complex.r)
3659              && MPFR_SIGN (expr->value.complex.r) >= 0
3660              && mpfr_zero_p (expr->value.complex.i)
3661              && MPFR_SIGN (expr->value.complex.i) >= 0;
3662
3663     default:
3664       break;
3665     }
3666   return false;
3667 }
3668
3669 /* Try to efficiently translate array(:) = 0.  Return NULL if this
3670    can't be done.  */
3671
3672 static tree
3673 gfc_trans_zero_assign (gfc_expr * expr)
3674 {
3675   tree dest, len, type;
3676   tree tmp;
3677   gfc_symbol *sym;
3678
3679   sym = expr->symtree->n.sym;
3680   dest = gfc_get_symbol_decl (sym);
3681
3682   type = TREE_TYPE (dest);
3683   if (POINTER_TYPE_P (type))
3684     type = TREE_TYPE (type);
3685   if (!GFC_ARRAY_TYPE_P (type))
3686     return NULL_TREE;
3687
3688   /* Determine the length of the array.  */
3689   len = GFC_TYPE_ARRAY_SIZE (type);
3690   if (!len || TREE_CODE (len) != INTEGER_CST)
3691     return NULL_TREE;
3692
3693   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3694   len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
3695                      fold_convert (gfc_array_index_type, tmp));
3696
3697   /* Convert arguments to the correct types.  */
3698   if (!POINTER_TYPE_P (TREE_TYPE (dest)))
3699     dest = gfc_build_addr_expr (pvoid_type_node, dest);
3700   else
3701     dest = fold_convert (pvoid_type_node, dest);
3702   len = fold_convert (size_type_node, len);
3703
3704   /* Construct call to __builtin_memset.  */
3705   tmp = build_call_expr (built_in_decls[BUILT_IN_MEMSET],
3706                          3, dest, integer_zero_node, len);
3707   return fold_convert (void_type_node, tmp);
3708 }
3709
3710
3711 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
3712    that constructs the call to __builtin_memcpy.  */
3713
3714 static tree
3715 gfc_build_memcpy_call (tree dst, tree src, tree len)
3716 {
3717   tree tmp;
3718
3719   /* Convert arguments to the correct types.  */
3720   if (!POINTER_TYPE_P (TREE_TYPE (dst)))
3721     dst = gfc_build_addr_expr (pvoid_type_node, dst);
3722   else
3723     dst = fold_convert (pvoid_type_node, dst);
3724
3725   if (!POINTER_TYPE_P (TREE_TYPE (src)))
3726     src = gfc_build_addr_expr (pvoid_type_node, src);
3727   else
3728     src = fold_convert (pvoid_type_node, src);
3729
3730   len = fold_convert (size_type_node, len);
3731
3732   /* Construct call to __builtin_memcpy.  */
3733   tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
3734   return fold_convert (void_type_node, tmp);
3735 }
3736
3737
3738 /* Try to efficiently translate dst(:) = src(:).  Return NULL if this
3739    can't be done.  EXPR1 is the destination/lhs and EXPR2 is the
3740    source/rhs, both are gfc_full_array_ref_p which have been checked for
3741    dependencies.  */
3742
3743 static tree
3744 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
3745 {
3746   tree dst, dlen, dtype;
3747   tree src, slen, stype;
3748   tree tmp;
3749
3750   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
3751   src = gfc_get_symbol_decl (expr2->symtree->n.sym);
3752
3753   dtype = TREE_TYPE (dst);
3754   if (POINTER_TYPE_P (dtype))
3755     dtype = TREE_TYPE (dtype);
3756   stype = TREE_TYPE (src);
3757   if (POINTER_TYPE_P (stype))
3758     stype = TREE_TYPE (stype);
3759
3760   if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
3761     return NULL_TREE;
3762
3763   /* Determine the lengths of the arrays.  */
3764   dlen = GFC_TYPE_ARRAY_SIZE (dtype);
3765   if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
3766     return NULL_TREE;
3767   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
3768   dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
3769                       fold_convert (gfc_array_index_type, tmp));
3770
3771   slen = GFC_TYPE_ARRAY_SIZE (stype);
3772   if (!slen || TREE_CODE (slen) != INTEGER_CST)
3773     return NULL_TREE;
3774   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
3775   slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
3776                       fold_convert (gfc_array_index_type, tmp));
3777
3778   /* Sanity check that they are the same.  This should always be
3779      the case, as we should already have checked for conformance.  */
3780   if (!tree_int_cst_equal (slen, dlen))
3781     return NULL_TREE;
3782
3783   return gfc_build_memcpy_call (dst, src, dlen);
3784 }
3785
3786
3787 /* Try to efficiently translate array(:) = (/ ... /).  Return NULL if
3788    this can't be done.  EXPR1 is the destination/lhs for which
3789    gfc_full_array_ref_p is true, and EXPR2 is the source/rhs.  */
3790
3791 static tree
3792 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
3793 {
3794   unsigned HOST_WIDE_INT nelem;
3795   tree dst, dtype;
3796   tree src, stype;
3797   tree len;
3798   tree tmp;
3799
3800   nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
3801   if (nelem == 0)
3802     return NULL_TREE;
3803
3804   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
3805   dtype = TREE_TYPE (dst);
3806   if (POINTER_TYPE_P (dtype))
3807     dtype = TREE_TYPE (dtype);
3808   if (!GFC_ARRAY_TYPE_P (dtype))
3809     return NULL_TREE;
3810
3811   /* Determine the lengths of the array.  */
3812   len = GFC_TYPE_ARRAY_SIZE (dtype);
3813   if (!len || TREE_CODE (len) != INTEGER_CST)
3814     return NULL_TREE;
3815
3816   /* Confirm that the constructor is the same size.  */
3817   if (compare_tree_int (len, nelem) != 0)
3818     return NULL_TREE;
3819
3820   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
3821   len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
3822                      fold_convert (gfc_array_index_type, tmp));
3823
3824   stype = gfc_typenode_for_spec (&expr2->ts);
3825   src = gfc_build_constant_array_constructor (expr2, stype);
3826
3827   stype = TREE_TYPE (src);
3828   if (POINTER_TYPE_P (stype))
3829     stype = TREE_TYPE (stype);
3830
3831   return gfc_build_memcpy_call (dst, src, len);
3832 }
3833
3834
3835 /* Subroutine of gfc_trans_assignment that actually scalarizes the
3836    assignment.  EXPR1 is the destination/RHS and EXPR2 is the source/LHS.  */
3837
3838 static tree
3839 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
3840 {
3841   gfc_se lse;
3842   gfc_se rse;
3843   gfc_ss *lss;
3844   gfc_ss *lss_section;
3845   gfc_ss *rss;
3846   gfc_loopinfo loop;
3847   tree tmp;
3848   stmtblock_t block;
3849   stmtblock_t body;
3850   bool l_is_temp;
3851
3852   /* Assignment of the form lhs = rhs.  */
3853   gfc_start_block (&block);
3854
3855   gfc_init_se (&lse, NULL);
3856   gfc_init_se (&rse, NULL);
3857
3858   /* Walk the lhs.  */
3859   lss = gfc_walk_expr (expr1);
3860   rss = NULL;
3861   if (lss != gfc_ss_terminator)
3862     {
3863       /* The assignment needs scalarization.  */
3864       lss_section = lss;
3865
3866       /* Find a non-scalar SS from the lhs.  */
3867       while (lss_section != gfc_ss_terminator
3868              && lss_section->type != GFC_SS_SECTION)
3869         lss_section = lss_section->next;
3870
3871       gcc_assert (lss_section != gfc_ss_terminator);
3872
3873       /* Initialize the scalarizer.  */
3874       gfc_init_loopinfo (&loop);
3875
3876       /* Walk the rhs.  */
3877       rss = gfc_walk_expr (expr2);
3878       if (rss == gfc_ss_terminator)
3879         {
3880           /* The rhs is scalar.  Add a ss for the expression.  */
3881           rss = gfc_get_ss ();
3882           rss->next = gfc_ss_terminator;
3883           rss->type = GFC_SS_SCALAR;
3884           rss->expr = expr2;
3885         }
3886       /* Associate the SS with the loop.  */
3887       gfc_add_ss_to_loop (&loop, lss);
3888       gfc_add_ss_to_loop (&loop, rss);
3889
3890       /* Calculate the bounds of the scalarization.  */
3891       gfc_conv_ss_startstride (&loop);
3892       /* Resolve any data dependencies in the statement.  */
3893       gfc_conv_resolve_dependencies (&loop, lss, rss);
3894       /* Setup the scalarizing loops.  */
3895       gfc_conv_loop_setup (&loop);
3896
3897       /* Setup the gfc_se structures.  */
3898       gfc_copy_loopinfo_to_se (&lse, &loop);
3899       gfc_copy_loopinfo_to_se (&rse, &loop);
3900
3901       rse.ss = rss;
3902       gfc_mark_ss_chain_used (rss, 1);
3903       if (loop.temp_ss == NULL)
3904         {
3905           lse.ss = lss;
3906           gfc_mark_ss_chain_used (lss, 1);
3907         }
3908       else
3909         {
3910           lse.ss = loop.temp_ss;
3911           gfc_mark_ss_chain_used (lss, 3);
3912           gfc_mark_ss_chain_used (loop.temp_ss, 3);
3913         }
3914
3915       /* Start the scalarized loop body.  */
3916       gfc_start_scalarized_body (&loop, &body);
3917     }
3918   else
3919     gfc_init_block (&body);
3920
3921   l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
3922
3923   /* Translate the expression.  */
3924   gfc_conv_expr (&rse, expr2);
3925
3926   if (l_is_temp)
3927     {
3928       gfc_conv_tmp_array_ref (&lse);
3929       gfc_advance_se_ss_chain (&lse);
3930     }
3931   else
3932     gfc_conv_expr (&lse, expr1);
3933
3934   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
3935                                  l_is_temp || init_flag,
3936                                  expr2->expr_type == EXPR_VARIABLE);
3937   gfc_add_expr_to_block (&body, tmp);
3938
3939   if (lss == gfc_ss_terminator)
3940     {
3941       /* Use the scalar assignment as is.  */
3942       gfc_add_block_to_block (&block, &body);
3943     }
3944   else
3945     {
3946       gcc_assert (lse.ss == gfc_ss_terminator
3947                   && rse.ss == gfc_ss_terminator);
3948
3949       if (l_is_temp)
3950         {
3951           gfc_trans_scalarized_loop_boundary (&loop, &body);
3952
3953           /* We need to copy the temporary to the actual lhs.  */
3954           gfc_init_se (&lse, NULL);
3955           gfc_init_se (&rse, NULL);
3956           gfc_copy_loopinfo_to_se (&lse, &loop);
3957           gfc_copy_loopinfo_to_se (&rse, &loop);
3958
3959           rse.ss = loop.temp_ss;
3960           lse.ss = lss;
3961
3962           gfc_conv_tmp_array_ref (&rse);
3963           gfc_advance_se_ss_chain (&rse);
3964           gfc_conv_expr (&lse, expr1);
3965
3966           gcc_assert (lse.ss == gfc_ss_terminator
3967                       && rse.ss == gfc_ss_terminator);
3968
3969           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
3970                                          false, false);
3971           gfc_add_expr_to_block (&body, tmp);
3972         }
3973
3974       /* Generate the copying loops.  */
3975       gfc_trans_scalarizing_loops (&loop, &body);
3976
3977       /* Wrap the whole thing up.  */
3978       gfc_add_block_to_block (&block, &loop.pre);
3979       gfc_add_block_to_block (&block, &loop.post);
3980
3981       gfc_cleanup_loop (&loop);
3982     }
3983
3984   return gfc_finish_block (&block);
3985 }
3986
3987
3988 /* Check whether EXPR, which is an EXPR_VARIABLE, is a copyable array.  */
3989
3990 static bool
3991 copyable_array_p (gfc_expr * expr)
3992 {
3993   /* First check it's an array.  */
3994   if (expr->rank < 1 || !expr->ref)
3995     return false;
3996
3997   /* Next check that it's of a simple enough type.  */
3998   switch (expr->ts.type)
3999     {
4000     case BT_INTEGER:
4001     case BT_REAL:
4002     case BT_COMPLEX:
4003     case BT_LOGICAL:
4004       return true;
4005
4006     case BT_CHARACTER:
4007       return false;
4008
4009     case BT_DERIVED:
4010       return !expr->ts.derived->attr.alloc_comp;
4011
4012     default:
4013       break;
4014     }
4015
4016   return false;
4017 }
4018
4019 /* Translate an assignment.  */
4020
4021 tree
4022 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
4023 {
4024   tree tmp;
4025
4026   /* Special case a single function returning an array.  */
4027   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
4028     {
4029       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
4030       if (tmp)
4031         return tmp;
4032     }
4033
4034   /* Special case assigning an array to zero.  */
4035   if (expr1->expr_type == EXPR_VARIABLE
4036       && expr1->rank > 0
4037       && expr1->ref
4038       && expr1->ref->next == NULL
4039       && gfc_full_array_ref_p (expr1->ref)
4040       && is_zero_initializer_p (expr2))
4041     {
4042       tmp = gfc_trans_zero_assign (expr1);
4043       if (tmp)
4044         return tmp;
4045     }
4046
4047   /* Special case copying one array to another.  */
4048   if (expr1->expr_type == EXPR_VARIABLE
4049       && copyable_array_p (expr1)
4050       && gfc_full_array_ref_p (expr1->ref)
4051       && expr2->expr_type == EXPR_VARIABLE
4052       && copyable_array_p (expr2)
4053       && gfc_full_array_ref_p (expr2->ref)
4054       && gfc_compare_types (&expr1->ts, &expr2->ts)
4055       && !gfc_check_dependency (expr1, expr2, 0))
4056     {
4057       tmp = gfc_trans_array_copy (expr1, expr2);
4058       if (tmp)
4059         return tmp;
4060     }
4061
4062   /* Special case initializing an array from a constant array constructor.  */
4063   if (expr1->expr_type == EXPR_VARIABLE
4064       && copyable_array_p (expr1)
4065       && gfc_full_array_ref_p (expr1->ref)
4066       && expr2->expr_type == EXPR_ARRAY
4067       && gfc_compare_types (&expr1->ts, &expr2->ts))
4068     {
4069       tmp = gfc_trans_array_constructor_copy (expr1, expr2);
4070       if (tmp)
4071         return tmp;
4072     }
4073
4074   /* Fallback to the scalarizer to generate explicit loops.  */
4075   return gfc_trans_assignment_1 (expr1, expr2, init_flag);
4076 }
4077
4078 tree
4079 gfc_trans_init_assign (gfc_code * code)
4080 {
4081   return gfc_trans_assignment (code->expr, code->expr2, true);
4082 }
4083
4084 tree
4085 gfc_trans_assign (gfc_code * code)
4086 {
4087   return gfc_trans_assignment (code->expr, code->expr2, false);
4088 }