OSDN Git Service

2006-11-10 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 by merging
1719        all the loop declarations into the current context.  */
1720       for (n = 0; n < loop.dimen; n++)
1721         {
1722           gfc_merge_block_scope (&body);
1723           body = loop.code[loop.order[n]];
1724         }
1725       gfc_merge_block_scope (&body);
1726     }
1727
1728   /* Add the post block after the second loop, so that any
1729      freeing of allocated memory is done at the right time.  */
1730   gfc_add_block_to_block (&parmse->pre, &loop.pre);
1731
1732   /**********Copy the temporary back again.*********/
1733
1734   gfc_init_se (&lse, NULL);
1735   gfc_init_se (&rse, NULL);
1736
1737   /* Walk the argument expression.  */
1738   lss = gfc_walk_expr (expr);
1739   rse.ss = loop.temp_ss;
1740   lse.ss = lss;
1741
1742   /* Initialize the scalarizer.  */
1743   gfc_init_loopinfo (&loop2);
1744   gfc_add_ss_to_loop (&loop2, lss);
1745
1746   /* Calculate the bounds of the scalarization.  */
1747   gfc_conv_ss_startstride (&loop2);
1748
1749   /* Setup the scalarizing loops.  */
1750   gfc_conv_loop_setup (&loop2);
1751
1752   gfc_copy_loopinfo_to_se (&lse, &loop2);
1753   gfc_copy_loopinfo_to_se (&rse, &loop2);
1754
1755   gfc_mark_ss_chain_used (lss, 1);
1756   gfc_mark_ss_chain_used (loop.temp_ss, 1);
1757
1758   /* Declare the variable to hold the temporary offset and start the
1759      scalarized loop body.  */
1760   offset = gfc_create_var (gfc_array_index_type, NULL);
1761   gfc_start_scalarized_body (&loop2, &body);
1762
1763   /* Build the offsets for the temporary from the loop variables.  The
1764      temporary array has lbounds of zero and strides of one in all
1765      dimensions, so this is very simple.  The offset is only computed
1766      outside the innermost loop, so the overall transfer could be
1767      optimized further.  */
1768   info = &rse.ss->data.info;
1769
1770   tmp_index = gfc_index_zero_node;
1771   for (n = info->dimen - 1; n > 0; n--)
1772     {
1773       tree tmp_str;
1774       tmp = rse.loop->loopvar[n];
1775       tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1776                          tmp, rse.loop->from[n]);
1777       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1778                          tmp, tmp_index);
1779
1780       tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1781                              rse.loop->to[n-1], rse.loop->from[n-1]);
1782       tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1783                              tmp_str, gfc_index_one_node);
1784
1785       tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
1786                                tmp, tmp_str);
1787     }
1788
1789   tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1790                            tmp_index, rse.loop->from[0]);
1791   gfc_add_modify_expr (&rse.loop->code[0], offset, tmp_index);
1792
1793   tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1794                            rse.loop->loopvar[0], offset);
1795
1796   /* Now use the offset for the reference.  */
1797   tmp = build_fold_indirect_ref (info->data);
1798   rse.expr = gfc_build_array_ref (tmp, tmp_index);
1799
1800   if (expr->ts.type == BT_CHARACTER)
1801     rse.string_length = expr->ts.cl->backend_decl;
1802
1803   gfc_conv_expr (&lse, expr);
1804
1805   gcc_assert (lse.ss == gfc_ss_terminator);
1806
1807   tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
1808   gfc_add_expr_to_block (&body, tmp);
1809   
1810   /* Generate the copying loops.  */
1811   gfc_trans_scalarizing_loops (&loop2, &body);
1812
1813   /* Wrap the whole thing up by adding the second loop to the post-block
1814      and following it by the post-block of the first loop.  In this way,
1815      if the temporary needs freeing, it is done after use!  */
1816   if (intent != INTENT_IN)
1817     {
1818       gfc_add_block_to_block (&parmse->post, &loop2.pre);
1819       gfc_add_block_to_block (&parmse->post, &loop2.post);
1820     }
1821
1822   gfc_add_block_to_block (&parmse->post, &loop.post);
1823
1824   gfc_cleanup_loop (&loop);
1825   gfc_cleanup_loop (&loop2);
1826
1827   /* Pass the string length to the argument expression.  */
1828   if (expr->ts.type == BT_CHARACTER)
1829     parmse->string_length = expr->ts.cl->backend_decl;
1830
1831   /* We want either the address for the data or the address of the descriptor,
1832      depending on the mode of passing array arguments.  */
1833   if (g77)
1834     parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
1835   else
1836     parmse->expr = build_fold_addr_expr (parmse->expr);
1837
1838   return;
1839 }
1840
1841 /* Is true if an array reference is followed by a component or substring
1842    reference.  */
1843
1844 static bool
1845 is_aliased_array (gfc_expr * e)
1846 {
1847   gfc_ref * ref;
1848   bool seen_array;
1849
1850   seen_array = false;   
1851   for (ref = e->ref; ref; ref = ref->next)
1852     {
1853       if (ref->type == REF_ARRAY
1854             && ref->u.ar.type != AR_ELEMENT)
1855         seen_array = true;
1856
1857       if (seen_array
1858             && ref->type != REF_ARRAY)
1859         return seen_array;
1860     }
1861   return false;
1862 }
1863
1864 /* Generate code for a procedure call.  Note can return se->post != NULL.
1865    If se->direct_byref is set then se->expr contains the return parameter.
1866    Return nonzero, if the call has alternate specifiers.  */
1867
1868 int
1869 gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
1870                         gfc_actual_arglist * arg, tree append_args)
1871 {
1872   gfc_interface_mapping mapping;
1873   tree arglist;
1874   tree retargs;
1875   tree tmp;
1876   tree fntype;
1877   gfc_se parmse;
1878   gfc_ss *argss;
1879   gfc_ss_info *info;
1880   int byref;
1881   int parm_kind;
1882   tree type;
1883   tree var;
1884   tree len;
1885   tree stringargs;
1886   gfc_formal_arglist *formal;
1887   int has_alternate_specifier = 0;
1888   bool need_interface_mapping;
1889   bool callee_alloc;
1890   gfc_typespec ts;
1891   gfc_charlen cl;
1892   gfc_expr *e;
1893   gfc_symbol *fsym;
1894   stmtblock_t post;
1895   enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
1896
1897   arglist = NULL_TREE;
1898   retargs = NULL_TREE;
1899   stringargs = NULL_TREE;
1900   var = NULL_TREE;
1901   len = NULL_TREE;
1902
1903   if (se->ss != NULL)
1904     {
1905       if (!sym->attr.elemental)
1906         {
1907           gcc_assert (se->ss->type == GFC_SS_FUNCTION);
1908           if (se->ss->useflags)
1909             {
1910               gcc_assert (gfc_return_by_reference (sym)
1911                       && sym->result->attr.dimension);
1912               gcc_assert (se->loop != NULL);
1913
1914               /* Access the previously obtained result.  */
1915               gfc_conv_tmp_array_ref (se);
1916               gfc_advance_se_ss_chain (se);
1917               return 0;
1918             }
1919         }
1920       info = &se->ss->data.info;
1921     }
1922   else
1923     info = NULL;
1924
1925   gfc_init_block (&post);
1926   gfc_init_interface_mapping (&mapping);
1927   need_interface_mapping = ((sym->ts.type == BT_CHARACTER
1928                                   && sym->ts.cl->length
1929                                   && sym->ts.cl->length->expr_type
1930                                                 != EXPR_CONSTANT)
1931                               || sym->attr.dimension);
1932   formal = sym->formal;
1933   /* Evaluate the arguments.  */
1934   for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
1935     {
1936       e = arg->expr;
1937       fsym = formal ? formal->sym : NULL;
1938       parm_kind = MISSING;
1939       if (e == NULL)
1940         {
1941
1942           if (se->ignore_optional)
1943             {
1944               /* Some intrinsics have already been resolved to the correct
1945                  parameters.  */
1946               continue;
1947             }
1948           else if (arg->label)
1949             {
1950               has_alternate_specifier = 1;
1951               continue;
1952             }
1953           else
1954             {
1955               /* Pass a NULL pointer for an absent arg.  */
1956               gfc_init_se (&parmse, NULL);
1957               parmse.expr = null_pointer_node;
1958               if (arg->missing_arg_type == BT_CHARACTER)
1959                 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
1960             }
1961         }
1962       else if (se->ss && se->ss->useflags)
1963         {
1964           /* An elemental function inside a scalarized loop.  */
1965           gfc_init_se (&parmse, se);
1966           gfc_conv_expr_reference (&parmse, e);
1967           parm_kind = ELEMENTAL;
1968         }
1969       else
1970         {
1971           /* A scalar or transformational function.  */
1972           gfc_init_se (&parmse, NULL);
1973           argss = gfc_walk_expr (e);
1974
1975           if (argss == gfc_ss_terminator)
1976             {
1977               gfc_conv_expr_reference (&parmse, e);
1978               parm_kind = SCALAR;
1979               if (fsym && fsym->attr.pointer
1980                   && e->expr_type != EXPR_NULL)
1981                 {
1982                   /* Scalar pointer dummy args require an extra level of
1983                   indirection. The null pointer already contains
1984                   this level of indirection.  */
1985                   parm_kind = SCALAR_POINTER;
1986                   parmse.expr = build_fold_addr_expr (parmse.expr);
1987                 }
1988             }
1989           else
1990             {
1991               /* If the procedure requires an explicit interface, the actual
1992                  argument is passed according to the corresponding formal
1993                  argument.  If the corresponding formal argument is a POINTER,
1994                  ALLOCATABLE or assumed shape, we do not use g77's calling
1995                  convention, and pass the address of the array descriptor
1996                  instead. Otherwise we use g77's calling convention.  */
1997               int f;
1998               f = (fsym != NULL)
1999                   && !(fsym->attr.pointer || fsym->attr.allocatable)
2000                   && fsym->as->type != AS_ASSUMED_SHAPE;
2001               f = f || !sym->attr.always_explicit;
2002
2003               if (e->expr_type == EXPR_VARIABLE
2004                     && is_aliased_array (e))
2005                 /* The actual argument is a component reference to an
2006                    array of derived types.  In this case, the argument
2007                    is converted to a temporary, which is passed and then
2008                    written back after the procedure call.  */
2009                 gfc_conv_aliased_arg (&parmse, e, f,
2010                         fsym ? fsym->attr.intent : INTENT_INOUT);
2011               else
2012                 gfc_conv_array_parameter (&parmse, e, argss, f);
2013
2014               /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 
2015                  allocated on entry, it must be deallocated.  */
2016               if (fsym && fsym->attr.allocatable
2017                   && fsym->attr.intent == INTENT_OUT)
2018                 {
2019                   tmp = e->symtree->n.sym->backend_decl;
2020                   if (e->symtree->n.sym->attr.dummy)
2021                     tmp = build_fold_indirect_ref (tmp);
2022                   tmp = gfc_trans_dealloc_allocated (tmp);
2023                   gfc_add_expr_to_block (&se->pre, tmp);
2024                 }
2025
2026             } 
2027         }
2028
2029       if (fsym)
2030         {
2031           if (e)
2032             {
2033               /* If an optional argument is itself an optional dummy
2034                  argument, check its presence and substitute a null
2035                  if absent.  */
2036               if (e->expr_type == EXPR_VARIABLE
2037                     && e->symtree->n.sym->attr.optional
2038                     && fsym->attr.optional)
2039                 gfc_conv_missing_dummy (&parmse, e, fsym->ts);
2040
2041               /* If an INTENT(OUT) dummy of derived type has a default
2042                  initializer, it must be (re)initialized here.  */
2043               if (fsym->attr.intent == INTENT_OUT
2044                     && fsym->ts.type == BT_DERIVED
2045                     && fsym->value)
2046                 {
2047                   gcc_assert (!fsym->attr.allocatable);
2048                   tmp = gfc_trans_assignment (e, fsym->value, false);
2049                   gfc_add_expr_to_block (&se->pre, tmp);
2050                 }
2051
2052               /* Obtain the character length of an assumed character
2053                  length procedure from the typespec.  */
2054               if (fsym->ts.type == BT_CHARACTER
2055                     && parmse.string_length == NULL_TREE
2056                     && e->ts.type == BT_PROCEDURE
2057                     && e->symtree->n.sym->ts.type == BT_CHARACTER
2058                     && e->symtree->n.sym->ts.cl->length != NULL)
2059                 {
2060                   gfc_conv_const_charlen (e->symtree->n.sym->ts.cl);
2061                   parmse.string_length
2062                         = e->symtree->n.sym->ts.cl->backend_decl;
2063                 }
2064             }
2065
2066           if (need_interface_mapping)
2067             gfc_add_interface_mapping (&mapping, fsym, &parmse);
2068         }
2069
2070       gfc_add_block_to_block (&se->pre, &parmse.pre);
2071       gfc_add_block_to_block (&post, &parmse.post);
2072
2073       /* Allocated allocatable components of derived types must be
2074          deallocated for INTENT(OUT) dummy arguments and non-variable
2075          scalars.  Non-variable arrays are dealt with in trans-array.c
2076          (gfc_conv_array_parameter).  */
2077       if (e && e->ts.type == BT_DERIVED
2078             && e->ts.derived->attr.alloc_comp
2079             && ((formal && formal->sym->attr.intent == INTENT_OUT)
2080                    ||
2081                 (e->expr_type != EXPR_VARIABLE && !e->rank)))
2082         {
2083           int parm_rank;
2084           tmp = build_fold_indirect_ref (parmse.expr);
2085           parm_rank = e->rank;
2086           switch (parm_kind)
2087             {
2088             case (ELEMENTAL):
2089             case (SCALAR):
2090               parm_rank = 0;
2091               break;
2092
2093             case (SCALAR_POINTER):
2094               tmp = build_fold_indirect_ref (tmp);
2095               break;
2096             case (ARRAY):
2097               tmp = parmse.expr;
2098               break;
2099             }
2100
2101           tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
2102           if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional)
2103             tmp = build3_v (COND_EXPR, gfc_conv_expr_present (e->symtree->n.sym),
2104                             tmp, build_empty_stmt ());
2105
2106           if (e->expr_type != EXPR_VARIABLE)
2107             /* Don't deallocate non-variables until they have been used.  */
2108             gfc_add_expr_to_block (&se->post, tmp);
2109           else 
2110             {
2111               gcc_assert (formal && formal->sym->attr.intent == INTENT_OUT);
2112               gfc_add_expr_to_block (&se->pre, tmp);
2113             }
2114         }
2115
2116       /* Character strings are passed as two parameters, a length and a
2117          pointer.  */
2118       if (parmse.string_length != NULL_TREE)
2119         stringargs = gfc_chainon_list (stringargs, parmse.string_length);
2120
2121       arglist = gfc_chainon_list (arglist, parmse.expr);
2122     }
2123   gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
2124
2125   ts = sym->ts;
2126   if (ts.type == BT_CHARACTER)
2127     {
2128       if (sym->ts.cl->length == NULL)
2129         {
2130           /* Assumed character length results are not allowed by 5.1.1.5 of the
2131              standard and are trapped in resolve.c; except in the case of SPREAD
2132              (and other intrinsics?) and dummy functions.  In the case of SPREAD,
2133              we take the character length of the first argument for the result.
2134              For dummies, we have to look through the formal argument list for
2135              this function and use the character length found there.*/
2136           if (!sym->attr.dummy)
2137             cl.backend_decl = TREE_VALUE (stringargs);
2138           else
2139             {
2140               formal = sym->ns->proc_name->formal;
2141               for (; formal; formal = formal->next)
2142                 if (strcmp (formal->sym->name, sym->name) == 0)
2143                   cl.backend_decl = formal->sym->ts.cl->backend_decl;
2144             }
2145         }
2146         else
2147         {
2148           /* Calculate the length of the returned string.  */
2149           gfc_init_se (&parmse, NULL);
2150           if (need_interface_mapping)
2151             gfc_apply_interface_mapping (&mapping, &parmse, sym->ts.cl->length);
2152           else
2153             gfc_conv_expr (&parmse, sym->ts.cl->length);
2154           gfc_add_block_to_block (&se->pre, &parmse.pre);
2155           gfc_add_block_to_block (&se->post, &parmse.post);
2156           cl.backend_decl = fold_convert (gfc_charlen_type_node, parmse.expr);
2157         }
2158
2159       /* Set up a charlen structure for it.  */
2160       cl.next = NULL;
2161       cl.length = NULL;
2162       ts.cl = &cl;
2163
2164       len = cl.backend_decl;
2165     }
2166
2167   byref = gfc_return_by_reference (sym);
2168   if (byref)
2169     {
2170       if (se->direct_byref)
2171         retargs = gfc_chainon_list (retargs, se->expr);
2172       else if (sym->result->attr.dimension)
2173         {
2174           gcc_assert (se->loop && info);
2175
2176           /* Set the type of the array.  */
2177           tmp = gfc_typenode_for_spec (&ts);
2178           info->dimen = se->loop->dimen;
2179
2180           /* Evaluate the bounds of the result, if known.  */
2181           gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
2182
2183           /* Create a temporary to store the result.  In case the function
2184              returns a pointer, the temporary will be a shallow copy and
2185              mustn't be deallocated.  */
2186           callee_alloc = sym->attr.allocatable || sym->attr.pointer;
2187           gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
2188                                        false, !sym->attr.pointer, callee_alloc,
2189                                        true);
2190
2191           /* Pass the temporary as the first argument.  */
2192           tmp = info->descriptor;
2193           tmp = build_fold_addr_expr (tmp);
2194           retargs = gfc_chainon_list (retargs, tmp);
2195         }
2196       else if (ts.type == BT_CHARACTER)
2197         {
2198           /* Pass the string length.  */
2199           type = gfc_get_character_type (ts.kind, ts.cl);
2200           type = build_pointer_type (type);
2201
2202           /* Return an address to a char[0:len-1]* temporary for
2203              character pointers.  */
2204           if (sym->attr.pointer || sym->attr.allocatable)
2205             {
2206               /* Build char[0:len-1] * pstr.  */
2207               tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
2208                                  build_int_cst (gfc_charlen_type_node, 1));
2209               tmp = build_range_type (gfc_array_index_type,
2210                                       gfc_index_zero_node, tmp);
2211               tmp = build_array_type (gfc_character1_type_node, tmp);
2212               var = gfc_create_var (build_pointer_type (tmp), "pstr");
2213
2214               /* Provide an address expression for the function arguments.  */
2215               var = build_fold_addr_expr (var);
2216             }
2217           else
2218             var = gfc_conv_string_tmp (se, type, len);
2219
2220           retargs = gfc_chainon_list (retargs, var);
2221         }
2222       else
2223         {
2224           gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
2225
2226           type = gfc_get_complex_type (ts.kind);
2227           var = build_fold_addr_expr (gfc_create_var (type, "cmplx"));
2228           retargs = gfc_chainon_list (retargs, var);
2229         }
2230
2231       /* Add the string length to the argument list.  */
2232       if (ts.type == BT_CHARACTER)
2233         retargs = gfc_chainon_list (retargs, len);
2234     }
2235   gfc_free_interface_mapping (&mapping);
2236
2237   /* Add the return arguments.  */
2238   arglist = chainon (retargs, arglist);
2239
2240   /* Add the hidden string length parameters to the arguments.  */
2241   arglist = chainon (arglist, stringargs);
2242
2243   /* We may want to append extra arguments here.  This is used e.g. for
2244      calls to libgfortran_matmul_??, which need extra information.  */
2245   if (append_args != NULL_TREE)
2246     arglist = chainon (arglist, append_args);
2247
2248   /* Generate the actual call.  */
2249   gfc_conv_function_val (se, sym);
2250   /* If there are alternate return labels, function type should be
2251      integer.  Can't modify the type in place though, since it can be shared
2252      with other functions.  */
2253   if (has_alternate_specifier
2254       && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
2255     {
2256       gcc_assert (! sym->attr.dummy);
2257       TREE_TYPE (sym->backend_decl)
2258         = build_function_type (integer_type_node,
2259                                TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
2260       se->expr = build_fold_addr_expr (sym->backend_decl);
2261     }
2262
2263   fntype = TREE_TYPE (TREE_TYPE (se->expr));
2264   se->expr = build3 (CALL_EXPR, TREE_TYPE (fntype), se->expr,
2265                      arglist, NULL_TREE);
2266
2267   /* If we have a pointer function, but we don't want a pointer, e.g.
2268      something like
2269         x = f()
2270      where f is pointer valued, we have to dereference the result.  */
2271   if (!se->want_pointer && !byref && sym->attr.pointer)
2272     se->expr = build_fold_indirect_ref (se->expr);
2273
2274   /* f2c calling conventions require a scalar default real function to
2275      return a double precision result.  Convert this back to default
2276      real.  We only care about the cases that can happen in Fortran 77.
2277   */
2278   if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
2279       && sym->ts.kind == gfc_default_real_kind
2280       && !sym->attr.always_explicit)
2281     se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
2282
2283   /* A pure function may still have side-effects - it may modify its
2284      parameters.  */
2285   TREE_SIDE_EFFECTS (se->expr) = 1;
2286 #if 0
2287   if (!sym->attr.pure)
2288     TREE_SIDE_EFFECTS (se->expr) = 1;
2289 #endif
2290
2291   if (byref)
2292     {
2293       /* Add the function call to the pre chain.  There is no expression.  */
2294       gfc_add_expr_to_block (&se->pre, se->expr);
2295       se->expr = NULL_TREE;
2296
2297       if (!se->direct_byref)
2298         {
2299           if (sym->attr.dimension)
2300             {
2301               if (flag_bounds_check)
2302                 {
2303                   /* Check the data pointer hasn't been modified.  This would
2304                      happen in a function returning a pointer.  */
2305                   tmp = gfc_conv_descriptor_data_get (info->descriptor);
2306                   tmp = fold_build2 (NE_EXPR, boolean_type_node,
2307                                      tmp, info->data);
2308                   gfc_trans_runtime_check (tmp, gfc_msg_fault, &se->pre, NULL);
2309                 }
2310               se->expr = info->descriptor;
2311               /* Bundle in the string length.  */
2312               se->string_length = len;
2313             }
2314           else if (sym->ts.type == BT_CHARACTER)
2315             {
2316               /* Dereference for character pointer results.  */
2317               if (sym->attr.pointer || sym->attr.allocatable)
2318                 se->expr = build_fold_indirect_ref (var);
2319               else
2320                 se->expr = var;
2321
2322               se->string_length = len;
2323             }
2324           else
2325             {
2326               gcc_assert (sym->ts.type == BT_COMPLEX && gfc_option.flag_f2c);
2327               se->expr = build_fold_indirect_ref (var);
2328             }
2329         }
2330     }
2331
2332   /* Follow the function call with the argument post block.  */
2333   if (byref)
2334     gfc_add_block_to_block (&se->pre, &post);
2335   else
2336     gfc_add_block_to_block (&se->post, &post);
2337
2338   return has_alternate_specifier;
2339 }
2340
2341
2342 /* Generate code to copy a string.  */
2343
2344 static void
2345 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
2346                        tree slength, tree src)
2347 {
2348   tree tmp, dlen, slen;
2349   tree dsc;
2350   tree ssc;
2351   tree cond;
2352   tree cond2;
2353   tree tmp2;
2354   tree tmp3;
2355   tree tmp4;
2356   stmtblock_t tempblock;
2357
2358   dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
2359   slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
2360
2361   /* Deal with single character specially.  */
2362   dsc = gfc_to_single_character (dlen, dest);
2363   ssc = gfc_to_single_character (slen, src);
2364   if (dsc != NULL_TREE && ssc != NULL_TREE)
2365     {
2366       gfc_add_modify_expr (block, dsc, ssc);
2367       return;
2368     }
2369
2370   /* Do nothing if the destination length is zero.  */
2371   cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
2372                       build_int_cst (gfc_charlen_type_node, 0));
2373
2374   /* The following code was previously in _gfortran_copy_string:
2375
2376        // The two strings may overlap so we use memmove.
2377        void
2378        copy_string (GFC_INTEGER_4 destlen, char * dest,
2379                     GFC_INTEGER_4 srclen, const char * src)
2380        {
2381          if (srclen >= destlen)
2382            {
2383              // This will truncate if too long.
2384              memmove (dest, src, destlen);
2385            }
2386          else
2387            {
2388              memmove (dest, src, srclen);
2389              // Pad with spaces.
2390              memset (&dest[srclen], ' ', destlen - srclen);
2391            }
2392        }
2393
2394      We're now doing it here for better optimization, but the logic
2395      is the same.  */
2396   
2397   /* Truncate string if source is too long.  */
2398   cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
2399   tmp2 = gfc_chainon_list (NULL_TREE, dest);
2400   tmp2 = gfc_chainon_list (tmp2, src);
2401   tmp2 = gfc_chainon_list (tmp2, dlen);
2402   tmp2 = build_function_call_expr (built_in_decls[BUILT_IN_MEMMOVE], tmp2);
2403
2404   /* Else copy and pad with spaces.  */
2405   tmp3 = gfc_chainon_list (NULL_TREE, dest);
2406   tmp3 = gfc_chainon_list (tmp3, src);
2407   tmp3 = gfc_chainon_list (tmp3, slen);
2408   tmp3 = build_function_call_expr (built_in_decls[BUILT_IN_MEMMOVE], tmp3);
2409
2410   tmp4 = fold_build2 (PLUS_EXPR, pchar_type_node, dest,
2411                       fold_convert (pchar_type_node, slen));
2412   tmp4 = gfc_chainon_list (NULL_TREE, tmp4);
2413   tmp4 = gfc_chainon_list (tmp4, build_int_cst
2414                                    (gfc_get_int_type (gfc_c_int_kind),
2415                                     lang_hooks.to_target_charset (' ')));
2416   tmp4 = gfc_chainon_list (tmp4, fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
2417                                               dlen, slen));
2418   tmp4 = build_function_call_expr (built_in_decls[BUILT_IN_MEMSET], tmp4);
2419
2420   gfc_init_block (&tempblock);
2421   gfc_add_expr_to_block (&tempblock, tmp3);
2422   gfc_add_expr_to_block (&tempblock, tmp4);
2423   tmp3 = gfc_finish_block (&tempblock);
2424
2425   /* The whole copy_string function is there.  */
2426   tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
2427   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
2428   gfc_add_expr_to_block (block, tmp);
2429 }
2430
2431
2432 /* Translate a statement function.
2433    The value of a statement function reference is obtained by evaluating the
2434    expression using the values of the actual arguments for the values of the
2435    corresponding dummy arguments.  */
2436
2437 static void
2438 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
2439 {
2440   gfc_symbol *sym;
2441   gfc_symbol *fsym;
2442   gfc_formal_arglist *fargs;
2443   gfc_actual_arglist *args;
2444   gfc_se lse;
2445   gfc_se rse;
2446   gfc_saved_var *saved_vars;
2447   tree *temp_vars;
2448   tree type;
2449   tree tmp;
2450   int n;
2451
2452   sym = expr->symtree->n.sym;
2453   args = expr->value.function.actual;
2454   gfc_init_se (&lse, NULL);
2455   gfc_init_se (&rse, NULL);
2456
2457   n = 0;
2458   for (fargs = sym->formal; fargs; fargs = fargs->next)
2459     n++;
2460   saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
2461   temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
2462
2463   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2464     {
2465       /* Each dummy shall be specified, explicitly or implicitly, to be
2466          scalar.  */
2467       gcc_assert (fargs->sym->attr.dimension == 0);
2468       fsym = fargs->sym;
2469
2470       /* Create a temporary to hold the value.  */
2471       type = gfc_typenode_for_spec (&fsym->ts);
2472       temp_vars[n] = gfc_create_var (type, fsym->name);
2473
2474       if (fsym->ts.type == BT_CHARACTER)
2475         {
2476           /* Copy string arguments.  */
2477           tree arglen;
2478
2479           gcc_assert (fsym->ts.cl && fsym->ts.cl->length
2480                   && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
2481
2482           arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2483           tmp = gfc_build_addr_expr (build_pointer_type (type),
2484                                      temp_vars[n]);
2485
2486           gfc_conv_expr (&rse, args->expr);
2487           gfc_conv_string_parameter (&rse);
2488           gfc_add_block_to_block (&se->pre, &lse.pre);
2489           gfc_add_block_to_block (&se->pre, &rse.pre);
2490
2491           gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
2492                                  rse.expr);
2493           gfc_add_block_to_block (&se->pre, &lse.post);
2494           gfc_add_block_to_block (&se->pre, &rse.post);
2495         }
2496       else
2497         {
2498           /* For everything else, just evaluate the expression.  */
2499           gfc_conv_expr (&lse, args->expr);
2500
2501           gfc_add_block_to_block (&se->pre, &lse.pre);
2502           gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
2503           gfc_add_block_to_block (&se->pre, &lse.post);
2504         }
2505
2506       args = args->next;
2507     }
2508
2509   /* Use the temporary variables in place of the real ones.  */
2510   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2511     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
2512
2513   gfc_conv_expr (se, sym->value);
2514
2515   if (sym->ts.type == BT_CHARACTER)
2516     {
2517       gfc_conv_const_charlen (sym->ts.cl);
2518
2519       /* Force the expression to the correct length.  */
2520       if (!INTEGER_CST_P (se->string_length)
2521           || tree_int_cst_lt (se->string_length,
2522                               sym->ts.cl->backend_decl))
2523         {
2524           type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
2525           tmp = gfc_create_var (type, sym->name);
2526           tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
2527           gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
2528                                  se->string_length, se->expr);
2529           se->expr = tmp;
2530         }
2531       se->string_length = sym->ts.cl->backend_decl;
2532     }
2533
2534   /* Restore the original variables.  */
2535   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2536     gfc_restore_sym (fargs->sym, &saved_vars[n]);
2537   gfc_free (saved_vars);
2538 }
2539
2540
2541 /* Translate a function expression.  */
2542
2543 static void
2544 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
2545 {
2546   gfc_symbol *sym;
2547
2548   if (expr->value.function.isym)
2549     {
2550       gfc_conv_intrinsic_function (se, expr);
2551       return;
2552     }
2553
2554   /* We distinguish statement functions from general functions to improve
2555      runtime performance.  */
2556   if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
2557     {
2558       gfc_conv_statement_function (se, expr);
2559       return;
2560     }
2561
2562   /* expr.value.function.esym is the resolved (specific) function symbol for
2563      most functions.  However this isn't set for dummy procedures.  */
2564   sym = expr->value.function.esym;
2565   if (!sym)
2566     sym = expr->symtree->n.sym;
2567   gfc_conv_function_call (se, sym, expr->value.function.actual, NULL_TREE);
2568 }
2569
2570
2571 static void
2572 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
2573 {
2574   gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
2575   gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
2576
2577   gfc_conv_tmp_array_ref (se);
2578   gfc_advance_se_ss_chain (se);
2579 }
2580
2581
2582 /* Build a static initializer.  EXPR is the expression for the initial value.
2583    The other parameters describe the variable of the component being 
2584    initialized. EXPR may be null.  */
2585
2586 tree
2587 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
2588                       bool array, bool pointer)
2589 {
2590   gfc_se se;
2591
2592   if (!(expr || pointer))
2593     return NULL_TREE;
2594
2595   if (array)
2596     {
2597       /* Arrays need special handling.  */
2598       if (pointer)
2599         return gfc_build_null_descriptor (type);
2600       else
2601         return gfc_conv_array_initializer (type, expr);
2602     }
2603   else if (pointer)
2604     return fold_convert (type, null_pointer_node);
2605   else
2606     {
2607       switch (ts->type)
2608         {
2609         case BT_DERIVED:
2610           gfc_init_se (&se, NULL);
2611           gfc_conv_structure (&se, expr, 1);
2612           return se.expr;
2613
2614         case BT_CHARACTER:
2615           return gfc_conv_string_init (ts->cl->backend_decl,expr);
2616
2617         default:
2618           gfc_init_se (&se, NULL);
2619           gfc_conv_constant (&se, expr);
2620           return se.expr;
2621         }
2622     }
2623 }
2624   
2625 static tree
2626 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2627 {
2628   gfc_se rse;
2629   gfc_se lse;
2630   gfc_ss *rss;
2631   gfc_ss *lss;
2632   stmtblock_t body;
2633   stmtblock_t block;
2634   gfc_loopinfo loop;
2635   int n;
2636   tree tmp;
2637
2638   gfc_start_block (&block);
2639
2640   /* Initialize the scalarizer.  */
2641   gfc_init_loopinfo (&loop);
2642
2643   gfc_init_se (&lse, NULL);
2644   gfc_init_se (&rse, NULL);
2645
2646   /* Walk the rhs.  */
2647   rss = gfc_walk_expr (expr);
2648   if (rss == gfc_ss_terminator)
2649     {
2650       /* The rhs is scalar.  Add a ss for the expression.  */
2651       rss = gfc_get_ss ();
2652       rss->next = gfc_ss_terminator;
2653       rss->type = GFC_SS_SCALAR;
2654       rss->expr = expr;
2655     }
2656
2657   /* Create a SS for the destination.  */
2658   lss = gfc_get_ss ();
2659   lss->type = GFC_SS_COMPONENT;
2660   lss->expr = NULL;
2661   lss->shape = gfc_get_shape (cm->as->rank);
2662   lss->next = gfc_ss_terminator;
2663   lss->data.info.dimen = cm->as->rank;
2664   lss->data.info.descriptor = dest;
2665   lss->data.info.data = gfc_conv_array_data (dest);
2666   lss->data.info.offset = gfc_conv_array_offset (dest);
2667   for (n = 0; n < cm->as->rank; n++)
2668     {
2669       lss->data.info.dim[n] = n;
2670       lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
2671       lss->data.info.stride[n] = gfc_index_one_node;
2672
2673       mpz_init (lss->shape[n]);
2674       mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
2675                cm->as->lower[n]->value.integer);
2676       mpz_add_ui (lss->shape[n], lss->shape[n], 1);
2677     }
2678   
2679   /* Associate the SS with the loop.  */
2680   gfc_add_ss_to_loop (&loop, lss);
2681   gfc_add_ss_to_loop (&loop, rss);
2682
2683   /* Calculate the bounds of the scalarization.  */
2684   gfc_conv_ss_startstride (&loop);
2685
2686   /* Setup the scalarizing loops.  */
2687   gfc_conv_loop_setup (&loop);
2688
2689   /* Setup the gfc_se structures.  */
2690   gfc_copy_loopinfo_to_se (&lse, &loop);
2691   gfc_copy_loopinfo_to_se (&rse, &loop);
2692
2693   rse.ss = rss;
2694   gfc_mark_ss_chain_used (rss, 1);
2695   lse.ss = lss;
2696   gfc_mark_ss_chain_used (lss, 1);
2697
2698   /* Start the scalarized loop body.  */
2699   gfc_start_scalarized_body (&loop, &body);
2700
2701   gfc_conv_tmp_array_ref (&lse);
2702   if (cm->ts.type == BT_CHARACTER)
2703     lse.string_length = cm->ts.cl->backend_decl;
2704
2705   gfc_conv_expr (&rse, expr);
2706
2707   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
2708   gfc_add_expr_to_block (&body, tmp);
2709
2710   gcc_assert (rse.ss == gfc_ss_terminator);
2711
2712   /* Generate the copying loops.  */
2713   gfc_trans_scalarizing_loops (&loop, &body);
2714
2715   /* Wrap the whole thing up.  */
2716   gfc_add_block_to_block (&block, &loop.pre);
2717   gfc_add_block_to_block (&block, &loop.post);
2718
2719   for (n = 0; n < cm->as->rank; n++)
2720     mpz_clear (lss->shape[n]);
2721   gfc_free (lss->shape);
2722
2723   gfc_cleanup_loop (&loop);
2724
2725   return gfc_finish_block (&block);
2726 }
2727
2728
2729 /* Assign a single component of a derived type constructor.  */
2730
2731 static tree
2732 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2733 {
2734   gfc_se se;
2735   gfc_se lse;
2736   gfc_ss *rss;
2737   stmtblock_t block;
2738   tree tmp;
2739   tree offset;
2740   int n;
2741
2742   gfc_start_block (&block);
2743
2744   if (cm->pointer)
2745     {
2746       gfc_init_se (&se, NULL);
2747       /* Pointer component.  */
2748       if (cm->dimension)
2749         {
2750           /* Array pointer.  */
2751           if (expr->expr_type == EXPR_NULL)
2752             gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
2753           else
2754             {
2755               rss = gfc_walk_expr (expr);
2756               se.direct_byref = 1;
2757               se.expr = dest;
2758               gfc_conv_expr_descriptor (&se, expr, rss);
2759               gfc_add_block_to_block (&block, &se.pre);
2760               gfc_add_block_to_block (&block, &se.post);
2761             }
2762         }
2763       else
2764         {
2765           /* Scalar pointers.  */
2766           se.want_pointer = 1;
2767           gfc_conv_expr (&se, expr);
2768           gfc_add_block_to_block (&block, &se.pre);
2769           gfc_add_modify_expr (&block, dest,
2770                                fold_convert (TREE_TYPE (dest), se.expr));
2771           gfc_add_block_to_block (&block, &se.post);
2772         }
2773     }
2774   else if (cm->dimension)
2775     {
2776       if (cm->allocatable && expr->expr_type == EXPR_NULL)
2777         gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
2778       else if (cm->allocatable)
2779         {
2780           tree tmp2;
2781
2782           gfc_init_se (&se, NULL);
2783  
2784           rss = gfc_walk_expr (expr);
2785           se.want_pointer = 0;
2786           gfc_conv_expr_descriptor (&se, expr, rss);
2787           gfc_add_block_to_block (&block, &se.pre);
2788
2789           tmp = fold_convert (TREE_TYPE (dest), se.expr);
2790           gfc_add_modify_expr (&block, dest, tmp);
2791
2792           if (cm->ts.type == BT_DERIVED && cm->ts.derived->attr.alloc_comp)
2793             tmp = gfc_copy_alloc_comp (cm->ts.derived, se.expr, dest,
2794                                        cm->as->rank);
2795           else
2796             tmp = gfc_duplicate_allocatable (dest, se.expr,
2797                                              TREE_TYPE(cm->backend_decl),
2798                                              cm->as->rank);
2799
2800           gfc_add_expr_to_block (&block, tmp);
2801
2802           gfc_add_block_to_block (&block, &se.post);
2803           gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
2804
2805           /* Shift the lbound and ubound of temporaries to being unity, rather
2806              than zero, based.  Calculate the offset for all cases.  */
2807           offset = gfc_conv_descriptor_offset (dest);
2808           gfc_add_modify_expr (&block, offset, gfc_index_zero_node);
2809           tmp2 =gfc_create_var (gfc_array_index_type, NULL);
2810           for (n = 0; n < expr->rank; n++)
2811             {
2812               if (expr->expr_type != EXPR_VARIABLE
2813                   && expr->expr_type != EXPR_CONSTANT)
2814                 {
2815                   tmp = gfc_conv_descriptor_ubound (dest, gfc_rank_cst[n]);
2816                   gfc_add_modify_expr (&block, tmp,
2817                                        fold_build2 (PLUS_EXPR,
2818                                                     gfc_array_index_type,
2819                                                     tmp, gfc_index_one_node));
2820                   tmp = gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]);
2821                   gfc_add_modify_expr (&block, tmp, gfc_index_one_node);
2822                 }
2823               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2824                                  gfc_conv_descriptor_lbound (dest,
2825                                                              gfc_rank_cst[n]),
2826                                  gfc_conv_descriptor_stride (dest,
2827                                                              gfc_rank_cst[n]));
2828               gfc_add_modify_expr (&block, tmp2, tmp);
2829               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
2830               gfc_add_modify_expr (&block, offset, tmp);
2831             }
2832         }
2833       else
2834         {
2835           tmp = gfc_trans_subarray_assign (dest, cm, expr);
2836           gfc_add_expr_to_block (&block, tmp);
2837         }
2838     }
2839   else if (expr->ts.type == BT_DERIVED)
2840     {
2841       if (expr->expr_type != EXPR_STRUCTURE)
2842         {
2843           gfc_init_se (&se, NULL);
2844           gfc_conv_expr (&se, expr);
2845           gfc_add_modify_expr (&block, dest,
2846                                fold_convert (TREE_TYPE (dest), se.expr));
2847         }
2848       else
2849         {
2850           /* Nested constructors.  */
2851           tmp = gfc_trans_structure_assign (dest, expr);
2852           gfc_add_expr_to_block (&block, tmp);
2853         }
2854     }
2855   else
2856     {
2857       /* Scalar component.  */
2858       gfc_init_se (&se, NULL);
2859       gfc_init_se (&lse, NULL);
2860
2861       gfc_conv_expr (&se, expr);
2862       if (cm->ts.type == BT_CHARACTER)
2863         lse.string_length = cm->ts.cl->backend_decl;
2864       lse.expr = dest;
2865       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
2866       gfc_add_expr_to_block (&block, tmp);
2867     }
2868   return gfc_finish_block (&block);
2869 }
2870
2871 /* Assign a derived type constructor to a variable.  */
2872
2873 static tree
2874 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
2875 {
2876   gfc_constructor *c;
2877   gfc_component *cm;
2878   stmtblock_t block;
2879   tree field;
2880   tree tmp;
2881
2882   gfc_start_block (&block);
2883   cm = expr->ts.derived->components;
2884   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
2885     {
2886       /* Skip absent members in default initializers.  */
2887       if (!c->expr)
2888         continue;
2889
2890       field = cm->backend_decl;
2891       tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
2892       tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
2893       gfc_add_expr_to_block (&block, tmp);
2894     }
2895   return gfc_finish_block (&block);
2896 }
2897
2898 /* Build an expression for a constructor. If init is nonzero then
2899    this is part of a static variable initializer.  */
2900
2901 void
2902 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
2903 {
2904   gfc_constructor *c;
2905   gfc_component *cm;
2906   tree val;
2907   tree type;
2908   tree tmp;
2909   VEC(constructor_elt,gc) *v = NULL;
2910
2911   gcc_assert (se->ss == NULL);
2912   gcc_assert (expr->expr_type == EXPR_STRUCTURE);
2913   type = gfc_typenode_for_spec (&expr->ts);
2914
2915   if (!init)
2916     {
2917       /* Create a temporary variable and fill it in.  */
2918       se->expr = gfc_create_var (type, expr->ts.derived->name);
2919       tmp = gfc_trans_structure_assign (se->expr, expr);
2920       gfc_add_expr_to_block (&se->pre, tmp);
2921       return;
2922     }
2923
2924   cm = expr->ts.derived->components;
2925
2926   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
2927     {
2928       /* Skip absent members in default initializers and allocatable
2929          components.  Although the latter have a default initializer
2930          of EXPR_NULL,... by default, the static nullify is not needed
2931          since this is done every time we come into scope.  */
2932       if (!c->expr || cm->allocatable)
2933         continue;
2934
2935       val = gfc_conv_initializer (c->expr, &cm->ts,
2936           TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
2937
2938       /* Append it to the constructor list.  */
2939       CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
2940     }
2941   se->expr = build_constructor (type, v);
2942 }
2943
2944
2945 /* Translate a substring expression.  */
2946
2947 static void
2948 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
2949 {
2950   gfc_ref *ref;
2951
2952   ref = expr->ref;
2953
2954   gcc_assert (ref->type == REF_SUBSTRING);
2955
2956   se->expr = gfc_build_string_const(expr->value.character.length,
2957                                     expr->value.character.string);
2958   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
2959   TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
2960
2961   gfc_conv_substring(se,ref,expr->ts.kind);
2962 }
2963
2964
2965 /* Entry point for expression translation.  Evaluates a scalar quantity.
2966    EXPR is the expression to be translated, and SE is the state structure if
2967    called from within the scalarized.  */
2968
2969 void
2970 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
2971 {
2972   if (se->ss && se->ss->expr == expr
2973       && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
2974     {
2975       /* Substitute a scalar expression evaluated outside the scalarization
2976          loop.  */
2977       se->expr = se->ss->data.scalar.expr;
2978       se->string_length = se->ss->string_length;
2979       gfc_advance_se_ss_chain (se);
2980       return;
2981     }
2982
2983   switch (expr->expr_type)
2984     {
2985     case EXPR_OP:
2986       gfc_conv_expr_op (se, expr);
2987       break;
2988
2989     case EXPR_FUNCTION:
2990       gfc_conv_function_expr (se, expr);
2991       break;
2992
2993     case EXPR_CONSTANT:
2994       gfc_conv_constant (se, expr);
2995       break;
2996
2997     case EXPR_VARIABLE:
2998       gfc_conv_variable (se, expr);
2999       break;
3000
3001     case EXPR_NULL:
3002       se->expr = null_pointer_node;
3003       break;
3004
3005     case EXPR_SUBSTRING:
3006       gfc_conv_substring_expr (se, expr);
3007       break;
3008
3009     case EXPR_STRUCTURE:
3010       gfc_conv_structure (se, expr, 0);
3011       break;
3012
3013     case EXPR_ARRAY:
3014       gfc_conv_array_constructor_expr (se, expr);
3015       break;
3016
3017     default:
3018       gcc_unreachable ();
3019       break;
3020     }
3021 }
3022
3023 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
3024    of an assignment.  */
3025 void
3026 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
3027 {
3028   gfc_conv_expr (se, expr);
3029   /* All numeric lvalues should have empty post chains.  If not we need to
3030      figure out a way of rewriting an lvalue so that it has no post chain.  */
3031   gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
3032 }
3033
3034 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
3035    numeric expressions.  Used for scalar values where inserting cleanup code
3036    is inconvenient.  */
3037 void
3038 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
3039 {
3040   tree val;
3041
3042   gcc_assert (expr->ts.type != BT_CHARACTER);
3043   gfc_conv_expr (se, expr);
3044   if (se->post.head)
3045     {
3046       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
3047       gfc_add_modify_expr (&se->pre, val, se->expr);
3048       se->expr = val;
3049       gfc_add_block_to_block (&se->pre, &se->post);
3050     }
3051 }
3052
3053 /* Helper to translate and expression and convert it to a particular type.  */
3054 void
3055 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
3056 {
3057   gfc_conv_expr_val (se, expr);
3058   se->expr = convert (type, se->expr);
3059 }
3060
3061
3062 /* Converts an expression so that it can be passed by reference.  Scalar
3063    values only.  */
3064
3065 void
3066 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
3067 {
3068   tree var;
3069
3070   if (se->ss && se->ss->expr == expr
3071       && se->ss->type == GFC_SS_REFERENCE)
3072     {
3073       se->expr = se->ss->data.scalar.expr;
3074       se->string_length = se->ss->string_length;
3075       gfc_advance_se_ss_chain (se);
3076       return;
3077     }
3078
3079   if (expr->ts.type == BT_CHARACTER)
3080     {
3081       gfc_conv_expr (se, expr);
3082       gfc_conv_string_parameter (se);
3083       return;
3084     }
3085
3086   if (expr->expr_type == EXPR_VARIABLE)
3087     {
3088       se->want_pointer = 1;
3089       gfc_conv_expr (se, expr);
3090       if (se->post.head)
3091         {
3092           var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3093           gfc_add_modify_expr (&se->pre, var, se->expr);
3094           gfc_add_block_to_block (&se->pre, &se->post);
3095           se->expr = var;
3096         }
3097       return;
3098     }
3099
3100   gfc_conv_expr (se, expr);
3101
3102   /* Create a temporary var to hold the value.  */
3103   if (TREE_CONSTANT (se->expr))
3104     {
3105       var = build_decl (CONST_DECL, NULL, TREE_TYPE (se->expr));
3106       DECL_INITIAL (var) = se->expr;
3107       pushdecl (var);
3108     }
3109   else
3110     {
3111       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3112       gfc_add_modify_expr (&se->pre, var, se->expr);
3113     }
3114   gfc_add_block_to_block (&se->pre, &se->post);
3115
3116   /* Take the address of that value.  */
3117   se->expr = build_fold_addr_expr (var);
3118 }
3119
3120
3121 tree
3122 gfc_trans_pointer_assign (gfc_code * code)
3123 {
3124   return gfc_trans_pointer_assignment (code->expr, code->expr2);
3125 }
3126
3127
3128 /* Generate code for a pointer assignment.  */
3129
3130 tree
3131 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
3132 {
3133   gfc_se lse;
3134   gfc_se rse;
3135   gfc_ss *lss;
3136   gfc_ss *rss;
3137   stmtblock_t block;
3138   tree desc;
3139   tree tmp;
3140
3141   gfc_start_block (&block);
3142
3143   gfc_init_se (&lse, NULL);
3144
3145   lss = gfc_walk_expr (expr1);
3146   rss = gfc_walk_expr (expr2);
3147   if (lss == gfc_ss_terminator)
3148     {
3149       /* Scalar pointers.  */
3150       lse.want_pointer = 1;
3151       gfc_conv_expr (&lse, expr1);
3152       gcc_assert (rss == gfc_ss_terminator);
3153       gfc_init_se (&rse, NULL);
3154       rse.want_pointer = 1;
3155       gfc_conv_expr (&rse, expr2);
3156       gfc_add_block_to_block (&block, &lse.pre);
3157       gfc_add_block_to_block (&block, &rse.pre);
3158       gfc_add_modify_expr (&block, lse.expr,
3159                            fold_convert (TREE_TYPE (lse.expr), rse.expr));
3160       gfc_add_block_to_block (&block, &rse.post);
3161       gfc_add_block_to_block (&block, &lse.post);
3162     }
3163   else
3164     {
3165       /* Array pointer.  */
3166       gfc_conv_expr_descriptor (&lse, expr1, lss);
3167       switch (expr2->expr_type)
3168         {
3169         case EXPR_NULL:
3170           /* Just set the data pointer to null.  */
3171           gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
3172           break;
3173
3174         case EXPR_VARIABLE:
3175           /* Assign directly to the pointer's descriptor.  */
3176           lse.direct_byref = 1;
3177           gfc_conv_expr_descriptor (&lse, expr2, rss);
3178           break;
3179
3180         default:
3181           /* Assign to a temporary descriptor and then copy that
3182              temporary to the pointer.  */
3183           desc = lse.expr;
3184           tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
3185
3186           lse.expr = tmp;
3187           lse.direct_byref = 1;
3188           gfc_conv_expr_descriptor (&lse, expr2, rss);
3189           gfc_add_modify_expr (&lse.pre, desc, tmp);
3190           break;
3191         }
3192       gfc_add_block_to_block (&block, &lse.pre);
3193       gfc_add_block_to_block (&block, &lse.post);
3194     }
3195   return gfc_finish_block (&block);
3196 }
3197
3198
3199 /* Makes sure se is suitable for passing as a function string parameter.  */
3200 /* TODO: Need to check all callers fo this function.  It may be abused.  */
3201
3202 void
3203 gfc_conv_string_parameter (gfc_se * se)
3204 {
3205   tree type;
3206
3207   if (TREE_CODE (se->expr) == STRING_CST)
3208     {
3209       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3210       return;
3211     }
3212
3213   type = TREE_TYPE (se->expr);
3214   if (TYPE_STRING_FLAG (type))
3215     {
3216       gcc_assert (TREE_CODE (se->expr) != INDIRECT_REF);
3217       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3218     }
3219
3220   gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
3221   gcc_assert (se->string_length
3222           && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
3223 }
3224
3225
3226 /* Generate code for assignment of scalar variables.  Includes character
3227    strings and derived types with allocatable components.  */
3228
3229 tree
3230 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
3231                          bool l_is_temp, bool r_is_var)
3232 {
3233   stmtblock_t block;
3234   tree tmp;
3235   tree cond;
3236
3237   gfc_init_block (&block);
3238
3239   if (ts.type == BT_CHARACTER)
3240     {
3241       gcc_assert (lse->string_length != NULL_TREE
3242               && rse->string_length != NULL_TREE);
3243
3244       gfc_conv_string_parameter (lse);
3245       gfc_conv_string_parameter (rse);
3246
3247       gfc_add_block_to_block (&block, &lse->pre);
3248       gfc_add_block_to_block (&block, &rse->pre);
3249
3250       gfc_trans_string_copy (&block, lse->string_length, lse->expr,
3251                              rse->string_length, rse->expr);
3252     }
3253   else if (ts.type == BT_DERIVED && ts.derived->attr.alloc_comp)
3254     {
3255       cond = NULL_TREE;
3256         
3257       /* Are the rhs and the lhs the same?  */
3258       if (r_is_var)
3259         {
3260           cond = fold_build2 (EQ_EXPR, boolean_type_node,
3261                               build_fold_addr_expr (lse->expr),
3262                               build_fold_addr_expr (rse->expr));
3263           cond = gfc_evaluate_now (cond, &lse->pre);
3264         }
3265
3266       /* Deallocate the lhs allocated components as long as it is not
3267          the same as the rhs.  */
3268       if (!l_is_temp)
3269         {
3270           tmp = gfc_deallocate_alloc_comp (ts.derived, lse->expr, 0);
3271           if (r_is_var)
3272             tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3273           gfc_add_expr_to_block (&lse->pre, tmp);
3274         }
3275         
3276       gfc_add_block_to_block (&block, &lse->pre);
3277       gfc_add_block_to_block (&block, &rse->pre);
3278
3279       gfc_add_modify_expr (&block, lse->expr,
3280                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
3281
3282       /* Do a deep copy if the rhs is a variable, if it is not the
3283          same as the lhs.  */
3284       if (r_is_var)
3285         {
3286           tmp = gfc_copy_alloc_comp (ts.derived, rse->expr, lse->expr, 0);
3287           tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3288           gfc_add_expr_to_block (&block, tmp);
3289         }
3290     }
3291   else
3292     {
3293       gfc_add_block_to_block (&block, &lse->pre);
3294       gfc_add_block_to_block (&block, &rse->pre);
3295
3296       gfc_add_modify_expr (&block, lse->expr,
3297                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
3298     }
3299
3300   gfc_add_block_to_block (&block, &lse->post);
3301   gfc_add_block_to_block (&block, &rse->post);
3302
3303   return gfc_finish_block (&block);
3304 }
3305
3306
3307 /* Try to translate array(:) = func (...), where func is a transformational
3308    array function, without using a temporary.  Returns NULL is this isn't the
3309    case.  */
3310
3311 static tree
3312 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
3313 {
3314   gfc_se se;
3315   gfc_ss *ss;
3316   gfc_ref * ref;
3317   bool seen_array_ref;
3318
3319   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
3320   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
3321     return NULL;
3322
3323   /* Elemental functions don't need a temporary anyway.  */
3324   if (expr2->value.function.esym != NULL
3325       && expr2->value.function.esym->attr.elemental)
3326     return NULL;
3327
3328   /* Fail if EXPR1 can't be expressed as a descriptor.  */
3329   if (gfc_ref_needs_temporary_p (expr1->ref))
3330     return NULL;
3331
3332   /* Functions returning pointers need temporaries.  */
3333   if (expr2->symtree->n.sym->attr.pointer 
3334       || expr2->symtree->n.sym->attr.allocatable)
3335     return NULL;
3336
3337   /* Check that no LHS component references appear during an array
3338      reference. This is needed because we do not have the means to
3339      span any arbitrary stride with an array descriptor. This check
3340      is not needed for the rhs because the function result has to be
3341      a complete type.  */
3342   seen_array_ref = false;
3343   for (ref = expr1->ref; ref; ref = ref->next)
3344     {
3345       if (ref->type == REF_ARRAY)
3346         seen_array_ref= true;
3347       else if (ref->type == REF_COMPONENT && seen_array_ref)
3348         return NULL;
3349     }
3350
3351   /* Check for a dependency.  */
3352   if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
3353                                    expr2->value.function.esym,
3354                                    expr2->value.function.actual))
3355     return NULL;
3356
3357   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
3358      functions.  */
3359   gcc_assert (expr2->value.function.isym
3360               || (gfc_return_by_reference (expr2->value.function.esym)
3361               && expr2->value.function.esym->result->attr.dimension));
3362
3363   ss = gfc_walk_expr (expr1);
3364   gcc_assert (ss != gfc_ss_terminator);
3365   gfc_init_se (&se, NULL);
3366   gfc_start_block (&se.pre);
3367   se.want_pointer = 1;
3368
3369   gfc_conv_array_parameter (&se, expr1, ss, 0);
3370
3371   se.direct_byref = 1;
3372   se.ss = gfc_walk_expr (expr2);
3373   gcc_assert (se.ss != gfc_ss_terminator);
3374   gfc_conv_function_expr (&se, expr2);
3375   gfc_add_block_to_block (&se.pre, &se.post);
3376
3377   return gfc_finish_block (&se.pre);
3378 }
3379
3380
3381 /* Translate an assignment.  Most of the code is concerned with
3382    setting up the scalarizer.  */
3383
3384 tree
3385 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
3386 {
3387   gfc_se lse;
3388   gfc_se rse;
3389   gfc_ss *lss;
3390   gfc_ss *lss_section;
3391   gfc_ss *rss;
3392   gfc_loopinfo loop;
3393   tree tmp;
3394   stmtblock_t block;
3395   stmtblock_t body;
3396   bool l_is_temp;
3397
3398   /* Special case a single function returning an array.  */
3399   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
3400     {
3401       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
3402       if (tmp)
3403         return tmp;
3404     }
3405
3406   /* Assignment of the form lhs = rhs.  */
3407   gfc_start_block (&block);
3408
3409   gfc_init_se (&lse, NULL);
3410   gfc_init_se (&rse, NULL);
3411
3412   /* Walk the lhs.  */
3413   lss = gfc_walk_expr (expr1);
3414   rss = NULL;
3415   if (lss != gfc_ss_terminator)
3416     {
3417       /* The assignment needs scalarization.  */
3418       lss_section = lss;
3419
3420       /* Find a non-scalar SS from the lhs.  */
3421       while (lss_section != gfc_ss_terminator
3422              && lss_section->type != GFC_SS_SECTION)
3423         lss_section = lss_section->next;
3424
3425       gcc_assert (lss_section != gfc_ss_terminator);
3426
3427       /* Initialize the scalarizer.  */
3428       gfc_init_loopinfo (&loop);
3429
3430       /* Walk the rhs.  */
3431       rss = gfc_walk_expr (expr2);
3432       if (rss == gfc_ss_terminator)
3433         {
3434           /* The rhs is scalar.  Add a ss for the expression.  */
3435           rss = gfc_get_ss ();
3436           rss->next = gfc_ss_terminator;
3437           rss->type = GFC_SS_SCALAR;
3438           rss->expr = expr2;
3439         }
3440       /* Associate the SS with the loop.  */
3441       gfc_add_ss_to_loop (&loop, lss);
3442       gfc_add_ss_to_loop (&loop, rss);
3443
3444       /* Calculate the bounds of the scalarization.  */
3445       gfc_conv_ss_startstride (&loop);
3446       /* Resolve any data dependencies in the statement.  */
3447       gfc_conv_resolve_dependencies (&loop, lss, rss);
3448       /* Setup the scalarizing loops.  */
3449       gfc_conv_loop_setup (&loop);
3450
3451       /* Setup the gfc_se structures.  */
3452       gfc_copy_loopinfo_to_se (&lse, &loop);
3453       gfc_copy_loopinfo_to_se (&rse, &loop);
3454
3455       rse.ss = rss;
3456       gfc_mark_ss_chain_used (rss, 1);
3457       if (loop.temp_ss == NULL)
3458         {
3459           lse.ss = lss;
3460           gfc_mark_ss_chain_used (lss, 1);
3461         }
3462       else
3463         {
3464           lse.ss = loop.temp_ss;
3465           gfc_mark_ss_chain_used (lss, 3);
3466           gfc_mark_ss_chain_used (loop.temp_ss, 3);
3467         }
3468
3469       /* Start the scalarized loop body.  */
3470       gfc_start_scalarized_body (&loop, &body);
3471     }
3472   else
3473     gfc_init_block (&body);
3474
3475   l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
3476
3477   /* Translate the expression.  */
3478   gfc_conv_expr (&rse, expr2);
3479
3480   if (l_is_temp)
3481     {
3482       gfc_conv_tmp_array_ref (&lse);
3483       gfc_advance_se_ss_chain (&lse);
3484     }
3485   else
3486     gfc_conv_expr (&lse, expr1);
3487
3488   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
3489                                  l_is_temp || init_flag,
3490                                  expr2->expr_type == EXPR_VARIABLE);
3491   gfc_add_expr_to_block (&body, tmp);
3492
3493   if (lss == gfc_ss_terminator)
3494     {
3495       /* Use the scalar assignment as is.  */
3496       gfc_add_block_to_block (&block, &body);
3497     }
3498   else
3499     {
3500       gcc_assert (lse.ss == gfc_ss_terminator
3501                   && rse.ss == gfc_ss_terminator);
3502
3503       if (l_is_temp)
3504         {
3505           gfc_trans_scalarized_loop_boundary (&loop, &body);
3506
3507           /* We need to copy the temporary to the actual lhs.  */
3508           gfc_init_se (&lse, NULL);
3509           gfc_init_se (&rse, NULL);
3510           gfc_copy_loopinfo_to_se (&lse, &loop);
3511           gfc_copy_loopinfo_to_se (&rse, &loop);
3512
3513           rse.ss = loop.temp_ss;
3514           lse.ss = lss;
3515
3516           gfc_conv_tmp_array_ref (&rse);
3517           gfc_advance_se_ss_chain (&rse);
3518           gfc_conv_expr (&lse, expr1);
3519
3520           gcc_assert (lse.ss == gfc_ss_terminator
3521                       && rse.ss == gfc_ss_terminator);
3522
3523           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
3524                                          false, false);
3525           gfc_add_expr_to_block (&body, tmp);
3526         }
3527
3528       /* Generate the copying loops.  */
3529       gfc_trans_scalarizing_loops (&loop, &body);
3530
3531       /* Wrap the whole thing up.  */
3532       gfc_add_block_to_block (&block, &loop.pre);
3533       gfc_add_block_to_block (&block, &loop.post);
3534
3535       gfc_cleanup_loop (&loop);
3536     }
3537
3538   return gfc_finish_block (&block);
3539 }
3540
3541 tree
3542 gfc_trans_init_assign (gfc_code * code)
3543 {
3544   return gfc_trans_assignment (code->expr, code->expr2, true);
3545 }
3546
3547 tree
3548 gfc_trans_assign (gfc_code * code)
3549 {
3550   return gfc_trans_assignment (code->expr, code->expr2, false);
3551 }