OSDN Git Service

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