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