OSDN Git Service

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