OSDN Git Service

b79d0743decd0edc1424f8a8cc9f3f3f60502fd0
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-expr.c
1 /* Expression translation
2    Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3    Contributed by Paul Brook <paul@nowt.org>
4    and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA.  */
22
23 /* trans-expr.c-- generate GENERIC trees for gfc_expr.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tree.h"
29 #include "convert.h"
30 #include "ggc.h"
31 #include "toplev.h"
32 #include "real.h"
33 #include "tree-gimple.h"
34 #include "flags.h"
35 #include "gfortran.h"
36 #include "trans.h"
37 #include "trans-const.h"
38 #include "trans-types.h"
39 #include "trans-array.h"
40 /* Only for gfc_trans_assign and gfc_trans_pointer_assign.  */
41 #include "trans-stmt.h"
42
43 static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
44
45 /* Copy the scalarization loop variables.  */
46
47 static void
48 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
49 {
50   dest->ss = src->ss;
51   dest->loop = src->loop;
52 }
53
54
55 /* Initialize a simple expression holder.
56
57    Care must be taken when multiple se are created with the same parent.
58    The child se must be kept in sync.  The easiest way is to delay creation
59    of a child se until after after the previous se has been translated.  */
60
61 void
62 gfc_init_se (gfc_se * se, gfc_se * parent)
63 {
64   memset (se, 0, sizeof (gfc_se));
65   gfc_init_block (&se->pre);
66   gfc_init_block (&se->post);
67
68   se->parent = parent;
69
70   if (parent)
71     gfc_copy_se_loopvars (se, parent);
72 }
73
74
75 /* Advances to the next SS in the chain.  Use this rather than setting
76    se->ss = se->ss->next because all the parents needs to be kept in sync.
77    See gfc_init_se.  */
78
79 void
80 gfc_advance_se_ss_chain (gfc_se * se)
81 {
82   gfc_se *p;
83
84   gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
85
86   p = se;
87   /* Walk down the parent chain.  */
88   while (p != NULL)
89     {
90       /* Simple consistency check.  */
91       gcc_assert (p->parent == NULL || p->parent->ss == p->ss);
92
93       p->ss = p->ss->next;
94
95       p = p->parent;
96     }
97 }
98
99
100 /* Ensures the result of the expression as either a temporary variable
101    or a constant so that it can be used repeatedly.  */
102
103 void
104 gfc_make_safe_expr (gfc_se * se)
105 {
106   tree var;
107
108   if (CONSTANT_CLASS_P (se->expr))
109     return;
110
111   /* We need a temporary for this result.  */
112   var = gfc_create_var (TREE_TYPE (se->expr), NULL);
113   gfc_add_modify_expr (&se->pre, var, se->expr);
114   se->expr = var;
115 }
116
117
118 /* Return an expression which determines if a dummy parameter is present.  */
119
120 tree
121 gfc_conv_expr_present (gfc_symbol * sym)
122 {
123   tree decl;
124
125   gcc_assert (sym->attr.dummy && sym->attr.optional);
126
127   decl = gfc_get_symbol_decl (sym);
128   if (TREE_CODE (decl) != PARM_DECL)
129     {
130       /* Array parameters use a temporary descriptor, we want the real
131          parameter.  */
132       gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
133              || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
134       decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
135     }
136   return build2 (NE_EXPR, boolean_type_node, decl,
137                  fold_convert (TREE_TYPE (decl), null_pointer_node));
138 }
139
140
141 /* Get the character length of an expression, looking through gfc_refs
142    if necessary.  */
143
144 tree
145 gfc_get_expr_charlen (gfc_expr *e)
146 {
147   gfc_ref *r;
148   tree length;
149
150   gcc_assert (e->expr_type == EXPR_VARIABLE 
151               && e->ts.type == BT_CHARACTER);
152   
153   length = NULL; /* To silence compiler warning.  */
154
155   /* First candidate: if the variable is of type CHARACTER, the
156      expression's length could be the length of the character
157      variable.  */
158   if (e->symtree->n.sym->ts.type == BT_CHARACTER)
159     length = e->symtree->n.sym->ts.cl->backend_decl;
160
161   /* Look through the reference chain for component references.  */
162   for (r = e->ref; r; r = r->next)
163     {
164       switch (r->type)
165         {
166         case REF_COMPONENT:
167           if (r->u.c.component->ts.type == BT_CHARACTER)
168             length = r->u.c.component->ts.cl->backend_decl;
169           break;
170
171         case REF_ARRAY:
172           /* Do nothing.  */
173           break;
174
175         default:
176           /* We should never got substring references here.  These will be
177              broken down by the scalarizer.  */
178           gcc_unreachable ();
179         }
180     }
181
182   gcc_assert (length != NULL);
183   return length;
184 }
185
186   
187
188 /* Generate code to initialize a string length variable. Returns the
189    value.  */
190
191 void
192 gfc_trans_init_string_length (gfc_charlen * cl, stmtblock_t * pblock)
193 {
194   gfc_se se;
195   tree tmp;
196
197   gfc_init_se (&se, NULL);
198   gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
199   gfc_add_block_to_block (pblock, &se.pre);
200
201   tmp = cl->backend_decl;
202   gfc_add_modify_expr (pblock, tmp, se.expr);
203 }
204
205
206 static void
207 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind)
208 {
209   tree tmp;
210   tree type;
211   tree var;
212   gfc_se start;
213   gfc_se end;
214
215   type = gfc_get_character_type (kind, ref->u.ss.length);
216   type = build_pointer_type (type);
217
218   var = NULL_TREE;
219   gfc_init_se (&start, se);
220   gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
221   gfc_add_block_to_block (&se->pre, &start.pre);
222
223   if (integer_onep (start.expr))
224     gfc_conv_string_parameter (se);
225   else
226     {
227       /* Change the start of the string.  */
228       if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
229         tmp = se->expr;
230       else
231         tmp = gfc_build_indirect_ref (se->expr);
232       tmp = gfc_build_array_ref (tmp, start.expr);
233       se->expr = gfc_build_addr_expr (type, tmp);
234     }
235
236   /* Length = end + 1 - start.  */
237   gfc_init_se (&end, se);
238   if (ref->u.ss.end == NULL)
239     end.expr = se->string_length;
240   else
241     {
242       gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
243       gfc_add_block_to_block (&se->pre, &end.pre);
244     }
245   tmp =
246     build2 (MINUS_EXPR, gfc_charlen_type_node,
247             fold_convert (gfc_charlen_type_node, integer_one_node),
248             start.expr);
249   tmp = build2 (PLUS_EXPR, gfc_charlen_type_node, end.expr, tmp);
250   se->string_length = fold (tmp);
251 }
252
253
254 /* Convert a derived type component reference.  */
255
256 static void
257 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
258 {
259   gfc_component *c;
260   tree tmp;
261   tree decl;
262   tree field;
263
264   c = ref->u.c.component;
265
266   gcc_assert (c->backend_decl);
267
268   field = c->backend_decl;
269   gcc_assert (TREE_CODE (field) == FIELD_DECL);
270   decl = se->expr;
271   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
272
273   se->expr = tmp;
274
275   if (c->ts.type == BT_CHARACTER)
276     {
277       tmp = c->ts.cl->backend_decl;
278       /* Components must always be constant length.  */
279       gcc_assert (tmp && INTEGER_CST_P (tmp));
280       se->string_length = tmp;
281     }
282
283   if (c->pointer && c->dimension == 0)
284     se->expr = gfc_build_indirect_ref (se->expr);
285 }
286
287
288 /* Return the contents of a variable. Also handles reference/pointer
289    variables (all Fortran pointer references are implicit).  */
290
291 static void
292 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
293 {
294   gfc_ref *ref;
295   gfc_symbol *sym;
296
297   sym = expr->symtree->n.sym;
298   if (se->ss != NULL)
299     {
300       /* Check that something hasn't gone horribly wrong.  */
301       gcc_assert (se->ss != gfc_ss_terminator);
302       gcc_assert (se->ss->expr == expr);
303
304       /* A scalarized term.  We already know the descriptor.  */
305       se->expr = se->ss->data.info.descriptor;
306       se->string_length = se->ss->string_length;
307       ref = se->ss->data.info.ref;
308     }
309   else
310     {
311       se->expr = gfc_get_symbol_decl (sym);
312
313       /* Procedure actual arguments.  */
314       if (sym->attr.flavor == FL_PROCEDURE
315           && se->expr != current_function_decl)
316         {
317           gcc_assert (se->want_pointer);
318           if (!sym->attr.dummy)
319             {
320               gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
321               se->expr = gfc_build_addr_expr (NULL, se->expr);
322             }
323           return;
324         }
325
326       /* Special case for assigning the return value of a function.
327          Self recursive functions must have an explicit return value.  */
328       if (se->expr == current_function_decl && sym->attr.function
329           && (sym->result == sym))
330         {
331           se->expr = gfc_get_fake_result_decl (sym);
332         }
333
334       /* Dereference scalar dummy variables.  */
335       if (sym->attr.dummy
336           && sym->ts.type != BT_CHARACTER
337           && !sym->attr.dimension)
338         se->expr = gfc_build_indirect_ref (se->expr);
339
340       /* Dereference pointer variables.  */
341       if ((sym->attr.pointer || sym->attr.allocatable)
342           && (sym->attr.dummy
343               || sym->attr.result
344               || sym->attr.function
345               || !sym->attr.dimension)
346           && sym->ts.type != BT_CHARACTER)
347         se->expr = gfc_build_indirect_ref (se->expr);
348
349       ref = expr->ref;
350     }
351
352   /* For character variables, also get the length.  */
353   if (sym->ts.type == BT_CHARACTER)
354     {
355       se->string_length = sym->ts.cl->backend_decl;
356       gcc_assert (se->string_length);
357     }
358
359   while (ref)
360     {
361       switch (ref->type)
362         {
363         case REF_ARRAY:
364           /* Return the descriptor if that's what we want and this is an array
365              section reference.  */
366           if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
367             return;
368 /* TODO: Pointers to single elements of array sections, eg elemental subs.  */
369           /* Return the descriptor for array pointers and allocations.  */
370           if (se->want_pointer
371               && ref->next == NULL && (se->descriptor_only))
372             return;
373
374           gfc_conv_array_ref (se, &ref->u.ar);
375           /* Return a pointer to an element.  */
376           break;
377
378         case REF_COMPONENT:
379           gfc_conv_component_ref (se, ref);
380           break;
381
382         case REF_SUBSTRING:
383           gfc_conv_substring (se, ref, expr->ts.kind);
384           break;
385
386         default:
387           gcc_unreachable ();
388           break;
389         }
390       ref = ref->next;
391     }
392   /* Pointer assignment, allocation or pass by reference.  Arrays are handled
393      separately.  */
394   if (se->want_pointer)
395     {
396       if (expr->ts.type == BT_CHARACTER)
397         gfc_conv_string_parameter (se);
398       else 
399         se->expr = gfc_build_addr_expr (NULL, se->expr);
400     }
401   if (se->ss != NULL)
402     gfc_advance_se_ss_chain (se);
403 }
404
405
406 /* Unary ops are easy... Or they would be if ! was a valid op.  */
407
408 static void
409 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
410 {
411   gfc_se operand;
412   tree type;
413
414   gcc_assert (expr->ts.type != BT_CHARACTER);
415   /* Initialize the operand.  */
416   gfc_init_se (&operand, se);
417   gfc_conv_expr_val (&operand, expr->value.op.op1);
418   gfc_add_block_to_block (&se->pre, &operand.pre);
419
420   type = gfc_typenode_for_spec (&expr->ts);
421
422   /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
423      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
424      All other unary operators have an equivalent GIMPLE unary operator.  */
425   if (code == TRUTH_NOT_EXPR)
426     se->expr = build2 (EQ_EXPR, type, operand.expr,
427                        convert (type, integer_zero_node));
428   else
429     se->expr = build1 (code, type, operand.expr);
430
431 }
432
433 /* Expand power operator to optimal multiplications when a value is raised
434    to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
435    Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
436    Programming", 3rd Edition, 1998.  */
437
438 /* This code is mostly duplicated from expand_powi in the backend.
439    We establish the "optimal power tree" lookup table with the defined size.
440    The items in the table are the exponents used to calculate the index
441    exponents. Any integer n less than the value can get an "addition chain",
442    with the first node being one.  */
443 #define POWI_TABLE_SIZE 256
444
445 /* The table is from builtins.c.  */
446 static const unsigned char powi_table[POWI_TABLE_SIZE] =
447   {
448       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
449       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
450       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
451      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
452      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
453      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
454      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
455      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
456      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
457      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
458      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
459      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
460      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
461      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
462      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
463      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
464      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
465      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
466      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
467      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
468      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
469      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
470      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
471      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
472      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
473     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
474     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
475     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
476     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
477     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
478     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
479     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
480   };
481
482 /* If n is larger than lookup table's max index, we use the "window 
483    method".  */
484 #define POWI_WINDOW_SIZE 3
485
486 /* Recursive function to expand the power operator. The temporary 
487    values are put in tmpvar. The function returns tmpvar[1] ** n.  */
488 static tree
489 gfc_conv_powi (gfc_se * se, int n, tree * tmpvar)
490 {
491   tree op0;
492   tree op1;
493   tree tmp;
494   int digit;
495
496   if (n < POWI_TABLE_SIZE)
497     {
498       if (tmpvar[n])
499         return tmpvar[n];
500
501       op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
502       op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
503     }
504   else if (n & 1)
505     {
506       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
507       op0 = gfc_conv_powi (se, n - digit, tmpvar);
508       op1 = gfc_conv_powi (se, digit, tmpvar);
509     }
510   else
511     {
512       op0 = gfc_conv_powi (se, n >> 1, tmpvar);
513       op1 = op0;
514     }
515
516   tmp = fold (build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1));
517   tmp = gfc_evaluate_now (tmp, &se->pre);
518
519   if (n < POWI_TABLE_SIZE)
520     tmpvar[n] = tmp;
521
522   return tmp;
523 }
524
525
526 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
527    return 1. Else return 0 and a call to runtime library functions
528    will have to be built.  */
529 static int
530 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
531 {
532   tree cond;
533   tree tmp;
534   tree type;
535   tree vartmp[POWI_TABLE_SIZE];
536   int n;
537   int sgn;
538
539   type = TREE_TYPE (lhs);
540   n = abs (TREE_INT_CST_LOW (rhs));
541   sgn = tree_int_cst_sgn (rhs);
542
543   if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations) || optimize_size)
544       && (n > 2 || n < -1))
545     return 0;
546
547   /* rhs == 0  */
548   if (sgn == 0)
549     {
550       se->expr = gfc_build_const (type, integer_one_node);
551       return 1;
552     }
553   /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1.  */
554   if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
555     {
556       tmp = build2 (EQ_EXPR, boolean_type_node, lhs,
557                     fold_convert (TREE_TYPE (lhs), integer_minus_one_node));
558       cond = build2 (EQ_EXPR, boolean_type_node, lhs,
559                      convert (TREE_TYPE (lhs), integer_one_node));
560
561       /* If rhs is even,
562          result = (lhs == 1 || lhs == -1) ? 1 : 0.  */
563       if ((n & 1) == 0)
564         {
565           tmp = build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
566           se->expr = build3 (COND_EXPR, type, tmp,
567                              convert (type, integer_one_node),
568                              convert (type, integer_zero_node));
569           return 1;
570         }
571       /* If rhs is odd,
572          result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0.  */
573       tmp = build3 (COND_EXPR, type, tmp,
574                     convert (type, integer_minus_one_node),
575                     convert (type, integer_zero_node));
576       se->expr = build3 (COND_EXPR, type, cond,
577                          convert (type, integer_one_node),
578                          tmp);
579       return 1;
580     }
581
582   memset (vartmp, 0, sizeof (vartmp));
583   vartmp[1] = lhs;
584   if (sgn == -1)
585     {
586       tmp = gfc_build_const (type, integer_one_node);
587       vartmp[1] = build2 (RDIV_EXPR, type, tmp, vartmp[1]);
588     }
589
590   se->expr = gfc_conv_powi (se, n, vartmp);
591
592   return 1;
593 }
594
595
596 /* Power op (**).  Constant integer exponent has special handling.  */
597
598 static void
599 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
600 {
601   tree gfc_int4_type_node;
602   int kind;
603   int ikind;
604   gfc_se lse;
605   gfc_se rse;
606   tree fndecl;
607   tree tmp;
608
609   gfc_init_se (&lse, se);
610   gfc_conv_expr_val (&lse, expr->value.op.op1);
611   gfc_add_block_to_block (&se->pre, &lse.pre);
612
613   gfc_init_se (&rse, se);
614   gfc_conv_expr_val (&rse, expr->value.op.op2);
615   gfc_add_block_to_block (&se->pre, &rse.pre);
616
617   if (expr->value.op.op2->ts.type == BT_INTEGER
618          && expr->value.op.op2->expr_type == EXPR_CONSTANT)
619     if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
620       return;        
621
622   gfc_int4_type_node = gfc_get_int_type (4);
623
624   kind = expr->value.op.op1->ts.kind;
625   switch (expr->value.op.op2->ts.type)
626     {
627     case BT_INTEGER:
628       ikind = expr->value.op.op2->ts.kind;
629       switch (ikind)
630         {
631         case 1:
632         case 2:
633           rse.expr = convert (gfc_int4_type_node, rse.expr);
634           /* Fall through.  */
635
636         case 4:
637           ikind = 0;
638           break;
639           
640         case 8:
641           ikind = 1;
642           break;
643
644         default:
645           gcc_unreachable ();
646         }
647       switch (kind)
648         {
649         case 1:
650         case 2:
651           if (expr->value.op.op1->ts.type == BT_INTEGER)
652             lse.expr = convert (gfc_int4_type_node, lse.expr);
653           else
654             gcc_unreachable ();
655           /* Fall through.  */
656
657         case 4:
658           kind = 0;
659           break;
660           
661         case 8:
662           kind = 1;
663           break;
664
665         default:
666           gcc_unreachable ();
667         }
668       
669       switch (expr->value.op.op1->ts.type)
670         {
671         case BT_INTEGER:
672           fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
673           break;
674
675         case BT_REAL:
676           fndecl = gfor_fndecl_math_powi[kind][ikind].real;
677           break;
678
679         case BT_COMPLEX:
680           fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
681           break;
682
683         default:
684           gcc_unreachable ();
685         }
686       break;
687
688     case BT_REAL:
689       switch (kind)
690         {
691         case 4:
692           fndecl = built_in_decls[BUILT_IN_POWF];
693           break;
694         case 8:
695           fndecl = built_in_decls[BUILT_IN_POW];
696           break;
697         default:
698           gcc_unreachable ();
699         }
700       break;
701
702     case BT_COMPLEX:
703       switch (kind)
704         {
705         case 4:
706           fndecl = gfor_fndecl_math_cpowf;
707           break;
708         case 8:
709           fndecl = gfor_fndecl_math_cpow;
710           break;
711         default:
712           gcc_unreachable ();
713         }
714       break;
715
716     default:
717       gcc_unreachable ();
718       break;
719     }
720
721   tmp = gfc_chainon_list (NULL_TREE, lse.expr);
722   tmp = gfc_chainon_list (tmp, rse.expr);
723   se->expr = fold (gfc_build_function_call (fndecl, tmp));
724 }
725
726
727 /* Generate code to allocate a string temporary.  */
728
729 tree
730 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
731 {
732   tree var;
733   tree tmp;
734   tree args;
735
736   gcc_assert (TREE_TYPE (len) == gfc_charlen_type_node);
737
738   if (gfc_can_put_var_on_stack (len))
739     {
740       /* Create a temporary variable to hold the result.  */
741       tmp = fold (build2 (MINUS_EXPR, gfc_charlen_type_node, len,
742                           convert (gfc_charlen_type_node,
743                                    integer_one_node)));
744       tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
745       tmp = build_array_type (gfc_character1_type_node, tmp);
746       var = gfc_create_var (tmp, "str");
747       var = gfc_build_addr_expr (type, var);
748     }
749   else
750     {
751       /* Allocate a temporary to hold the result.  */
752       var = gfc_create_var (type, "pstr");
753       args = gfc_chainon_list (NULL_TREE, len);
754       tmp = gfc_build_function_call (gfor_fndecl_internal_malloc, args);
755       tmp = convert (type, tmp);
756       gfc_add_modify_expr (&se->pre, var, tmp);
757
758       /* Free the temporary afterwards.  */
759       tmp = convert (pvoid_type_node, var);
760       args = gfc_chainon_list (NULL_TREE, tmp);
761       tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
762       gfc_add_expr_to_block (&se->post, tmp);
763     }
764
765   return var;
766 }
767
768
769 /* Handle a string concatenation operation.  A temporary will be allocated to
770    hold the result.  */
771
772 static void
773 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
774 {
775   gfc_se lse;
776   gfc_se rse;
777   tree len;
778   tree type;
779   tree var;
780   tree args;
781   tree tmp;
782
783   gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
784           && expr->value.op.op2->ts.type == BT_CHARACTER);
785
786   gfc_init_se (&lse, se);
787   gfc_conv_expr (&lse, expr->value.op.op1);
788   gfc_conv_string_parameter (&lse);
789   gfc_init_se (&rse, se);
790   gfc_conv_expr (&rse, expr->value.op.op2);
791   gfc_conv_string_parameter (&rse);
792
793   gfc_add_block_to_block (&se->pre, &lse.pre);
794   gfc_add_block_to_block (&se->pre, &rse.pre);
795
796   type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
797   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
798   if (len == NULL_TREE)
799     {
800       len = fold (build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
801                           lse.string_length, rse.string_length));
802     }
803
804   type = build_pointer_type (type);
805
806   var = gfc_conv_string_tmp (se, type, len);
807
808   /* Do the actual concatenation.  */
809   args = NULL_TREE;
810   args = gfc_chainon_list (args, len);
811   args = gfc_chainon_list (args, var);
812   args = gfc_chainon_list (args, lse.string_length);
813   args = gfc_chainon_list (args, lse.expr);
814   args = gfc_chainon_list (args, rse.string_length);
815   args = gfc_chainon_list (args, rse.expr);
816   tmp = gfc_build_function_call (gfor_fndecl_concat_string, args);
817   gfc_add_expr_to_block (&se->pre, tmp);
818
819   /* Add the cleanup for the operands.  */
820   gfc_add_block_to_block (&se->pre, &rse.post);
821   gfc_add_block_to_block (&se->pre, &lse.post);
822
823   se->expr = var;
824   se->string_length = len;
825 }
826
827
828 /* Translates an op expression. Common (binary) cases are handled by this
829    function, others are passed on. Recursion is used in either case.
830    We use the fact that (op1.ts == op2.ts) (except for the power
831    operator **).
832    Operators need no special handling for scalarized expressions as long as
833    they call gfc_conv_simple_val to get their operands.
834    Character strings get special handling.  */
835
836 static void
837 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
838 {
839   enum tree_code code;
840   gfc_se lse;
841   gfc_se rse;
842   tree type;
843   tree tmp;
844   int lop;
845   int checkstring;
846
847   checkstring = 0;
848   lop = 0;
849   switch (expr->value.op.operator)
850     {
851     case INTRINSIC_UPLUS:
852       gfc_conv_expr (se, expr->value.op.op1);
853       return;
854
855     case INTRINSIC_UMINUS:
856       gfc_conv_unary_op (NEGATE_EXPR, se, expr);
857       return;
858
859     case INTRINSIC_NOT:
860       gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
861       return;
862
863     case INTRINSIC_PLUS:
864       code = PLUS_EXPR;
865       break;
866
867     case INTRINSIC_MINUS:
868       code = MINUS_EXPR;
869       break;
870
871     case INTRINSIC_TIMES:
872       code = MULT_EXPR;
873       break;
874
875     case INTRINSIC_DIVIDE:
876       /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
877          an integer, we must round towards zero, so we use a
878          TRUNC_DIV_EXPR.  */
879       if (expr->ts.type == BT_INTEGER)
880         code = TRUNC_DIV_EXPR;
881       else
882         code = RDIV_EXPR;
883       break;
884
885     case INTRINSIC_POWER:
886       gfc_conv_power_op (se, expr);
887       return;
888
889     case INTRINSIC_CONCAT:
890       gfc_conv_concat_op (se, expr);
891       return;
892
893     case INTRINSIC_AND:
894       code = TRUTH_ANDIF_EXPR;
895       lop = 1;
896       break;
897
898     case INTRINSIC_OR:
899       code = TRUTH_ORIF_EXPR;
900       lop = 1;
901       break;
902
903       /* EQV and NEQV only work on logicals, but since we represent them
904          as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
905     case INTRINSIC_EQ:
906     case INTRINSIC_EQV:
907       code = EQ_EXPR;
908       checkstring = 1;
909       lop = 1;
910       break;
911
912     case INTRINSIC_NE:
913     case INTRINSIC_NEQV:
914       code = NE_EXPR;
915       checkstring = 1;
916       lop = 1;
917       break;
918
919     case INTRINSIC_GT:
920       code = GT_EXPR;
921       checkstring = 1;
922       lop = 1;
923       break;
924
925     case INTRINSIC_GE:
926       code = GE_EXPR;
927       checkstring = 1;
928       lop = 1;
929       break;
930
931     case INTRINSIC_LT:
932       code = LT_EXPR;
933       checkstring = 1;
934       lop = 1;
935       break;
936
937     case INTRINSIC_LE:
938       code = LE_EXPR;
939       checkstring = 1;
940       lop = 1;
941       break;
942
943     case INTRINSIC_USER:
944     case INTRINSIC_ASSIGN:
945       /* These should be converted into function calls by the frontend.  */
946       gcc_unreachable ();
947
948     default:
949       fatal_error ("Unknown intrinsic op");
950       return;
951     }
952
953   /* The only exception to this is **, which is handled separately anyway.  */
954   gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
955
956   if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
957     checkstring = 0;
958
959   /* lhs */
960   gfc_init_se (&lse, se);
961   gfc_conv_expr (&lse, expr->value.op.op1);
962   gfc_add_block_to_block (&se->pre, &lse.pre);
963
964   /* rhs */
965   gfc_init_se (&rse, se);
966   gfc_conv_expr (&rse, expr->value.op.op2);
967   gfc_add_block_to_block (&se->pre, &rse.pre);
968
969   /* For string comparisons we generate a library call, and compare the return
970      value with 0.  */
971   if (checkstring)
972     {
973       gfc_conv_string_parameter (&lse);
974       gfc_conv_string_parameter (&rse);
975       tmp = NULL_TREE;
976       tmp = gfc_chainon_list (tmp, lse.string_length);
977       tmp = gfc_chainon_list (tmp, lse.expr);
978       tmp = gfc_chainon_list (tmp, rse.string_length);
979       tmp = gfc_chainon_list (tmp, rse.expr);
980
981       /* Build a call for the comparison.  */
982       lse.expr = gfc_build_function_call (gfor_fndecl_compare_string, tmp);
983       gfc_add_block_to_block (&lse.post, &rse.post);
984
985       rse.expr = integer_zero_node;
986     }
987
988   type = gfc_typenode_for_spec (&expr->ts);
989
990   if (lop)
991     {
992       /* The result of logical ops is always boolean_type_node.  */
993       tmp = fold (build2 (code, type, lse.expr, rse.expr));
994       se->expr = convert (type, tmp);
995     }
996   else
997     se->expr = fold (build2 (code, type, lse.expr, rse.expr));
998
999   /* Add the post blocks.  */
1000   gfc_add_block_to_block (&se->post, &rse.post);
1001   gfc_add_block_to_block (&se->post, &lse.post);
1002 }
1003
1004
1005 static void
1006 gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
1007 {
1008   tree tmp;
1009
1010   if (sym->attr.dummy)
1011     {
1012       tmp = gfc_get_symbol_decl (sym);
1013       gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1014               && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
1015
1016       se->expr = tmp;
1017     }
1018   else
1019     {
1020       if (!sym->backend_decl)
1021         sym->backend_decl = gfc_get_extern_function_decl (sym);
1022
1023       tmp = sym->backend_decl;
1024       gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1025       se->expr = gfc_build_addr_expr (NULL, tmp);
1026     }
1027 }
1028
1029
1030 /* Generate code for a procedure call.  Note can return se->post != NULL.
1031    If se->direct_byref is set then se->expr contains the return parameter.  */
1032
1033 void
1034 gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
1035                         gfc_actual_arglist * arg)
1036 {
1037   tree arglist;
1038   tree tmp;
1039   tree fntype;
1040   gfc_se parmse;
1041   gfc_ss *argss;
1042   gfc_ss_info *info;
1043   int byref;
1044   tree type;
1045   tree var;
1046   tree len;
1047   tree stringargs;
1048   gfc_formal_arglist *formal;
1049
1050   arglist = NULL_TREE;
1051   stringargs = NULL_TREE;
1052   var = NULL_TREE;
1053   len = NULL_TREE;
1054
1055   if (se->ss != NULL)
1056     {
1057       if (!sym->attr.elemental)
1058         {
1059           gcc_assert (se->ss->type == GFC_SS_FUNCTION);
1060           if (se->ss->useflags)
1061             {
1062               gcc_assert (gfc_return_by_reference (sym)
1063                       && sym->result->attr.dimension);
1064               gcc_assert (se->loop != NULL);
1065
1066               /* Access the previously obtained result.  */
1067               gfc_conv_tmp_array_ref (se);
1068               gfc_advance_se_ss_chain (se);
1069               return;
1070             }
1071         }
1072       info = &se->ss->data.info;
1073     }
1074   else
1075     info = NULL;
1076
1077   byref = gfc_return_by_reference (sym);
1078   if (byref)
1079     {
1080       if (se->direct_byref)
1081         arglist = gfc_chainon_list (arglist, se->expr);
1082       else if (sym->result->attr.dimension)
1083         {
1084           gcc_assert (se->loop && se->ss);
1085           /* Set the type of the array.  */
1086           tmp = gfc_typenode_for_spec (&sym->ts);
1087           info->dimen = se->loop->dimen;
1088           /* Allocate a temporary to store the result.  */
1089           gfc_trans_allocate_temp_array (se->loop, info, tmp);
1090
1091           /* Zero the first stride to indicate a temporary.  */
1092           tmp =
1093             gfc_conv_descriptor_stride (info->descriptor, gfc_rank_cst[0]);
1094           gfc_add_modify_expr (&se->pre, tmp,
1095                                convert (TREE_TYPE (tmp), integer_zero_node));
1096           /* Pass the temporary as the first argument.  */
1097           tmp = info->descriptor;
1098           tmp = gfc_build_addr_expr (NULL, tmp);
1099           arglist = gfc_chainon_list (arglist, tmp);
1100         }
1101       else if (sym->ts.type == BT_CHARACTER)
1102         {
1103           gcc_assert (sym->ts.cl && sym->ts.cl->length
1104                   && sym->ts.cl->length->expr_type == EXPR_CONSTANT);
1105           len = gfc_conv_mpz_to_tree
1106             (sym->ts.cl->length->value.integer, sym->ts.cl->length->ts.kind);
1107           sym->ts.cl->backend_decl = len;
1108           type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
1109           type = build_pointer_type (type);
1110
1111           var = gfc_conv_string_tmp (se, type, len);
1112           arglist = gfc_chainon_list (arglist, var);
1113           arglist = gfc_chainon_list (arglist, 
1114                                       convert (gfc_charlen_type_node, len));
1115         }
1116       else
1117         gcc_unreachable ();
1118     }
1119
1120   formal = sym->formal;
1121   /* Evaluate the arguments.  */
1122   for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
1123     {
1124       if (arg->expr == NULL)
1125         {
1126
1127           if (se->ignore_optional)
1128             {
1129               /* Some intrinsics have already been resolved to the correct
1130                  parameters.  */
1131               continue;
1132             }
1133           else if (arg->label)
1134             {
1135               has_alternate_specifier = 1;
1136               continue;
1137             }
1138           else
1139             {
1140               /* Pass a NULL pointer for an absent arg.  */
1141               gfc_init_se (&parmse, NULL);
1142               parmse.expr = null_pointer_node;
1143               if (arg->missing_arg_type == BT_CHARACTER)
1144                 {
1145                   stringargs =
1146                     gfc_chainon_list (stringargs,
1147                                       convert (gfc_charlen_type_node,
1148                                                integer_zero_node));
1149                 }
1150             }
1151         }
1152       else if (se->ss && se->ss->useflags)
1153         {
1154           /* An elemental function inside a scalarized loop.  */
1155           gfc_init_se (&parmse, se);
1156           gfc_conv_expr_reference (&parmse, arg->expr);
1157         }
1158       else
1159         {
1160           /* A scalar or transformational function.  */
1161           gfc_init_se (&parmse, NULL);
1162           argss = gfc_walk_expr (arg->expr);
1163
1164           if (argss == gfc_ss_terminator)
1165             {
1166               gfc_conv_expr_reference (&parmse, arg->expr);
1167               if (formal && formal->sym->attr.pointer
1168                   && arg->expr->expr_type != EXPR_NULL)
1169                 {
1170                   /* Scalar pointer dummy args require an extra level of
1171                      indirection. The null pointer already contains
1172                      this level of indirection.  */
1173                   parmse.expr = gfc_build_addr_expr (NULL, parmse.expr);
1174                 }
1175             }
1176           else
1177             {
1178               /* If the procedure requires an explicit interface, the
1179                  actual argument is passed according to the
1180                  corresponding formal argument.  If the corresponding
1181                  formal argument is a POINTER or assumed shape, we do
1182                  not use g77's calling convention, and pass the
1183                  address of the array descriptor instead. Otherwise we
1184                  use g77's calling convention.  */
1185               int f;
1186               f = (formal != NULL)
1187                   && !formal->sym->attr.pointer
1188                   && formal->sym->as->type != AS_ASSUMED_SHAPE;
1189               f = f || !sym->attr.always_explicit;
1190               gfc_conv_array_parameter (&parmse, arg->expr, argss, f);
1191             } 
1192         }
1193
1194       gfc_add_block_to_block (&se->pre, &parmse.pre);
1195       gfc_add_block_to_block (&se->post, &parmse.post);
1196
1197       /* Character strings are passed as two parameters, a length and a
1198          pointer.  */
1199       if (parmse.string_length != NULL_TREE)
1200         stringargs = gfc_chainon_list (stringargs, parmse.string_length);
1201
1202       arglist = gfc_chainon_list (arglist, parmse.expr);
1203     }
1204
1205   /* Add the hidden string length parameters to the arguments.  */
1206   arglist = chainon (arglist, stringargs);
1207
1208   /* Generate the actual call.  */
1209   gfc_conv_function_val (se, sym);
1210   /* If there are alternate return labels, function type should be
1211      integer.  */
1212   if (has_alternate_specifier)
1213     TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
1214
1215   fntype = TREE_TYPE (TREE_TYPE (se->expr));
1216   se->expr = build3 (CALL_EXPR, TREE_TYPE (fntype), se->expr,
1217                      arglist, NULL_TREE);
1218
1219   /* If we have a pointer function, but we don't want a pointer, e.g.
1220      something like
1221         x = f()
1222      where f is pointer valued, we have to dereference the result.  */
1223   if (!se->want_pointer && !byref
1224       && (sym->attr.pointer || (sym->result && sym->result->attr.pointer)))
1225     se->expr = gfc_build_indirect_ref (se->expr);
1226
1227   /* A pure function may still have side-effects - it may modify its
1228      parameters.  */
1229   TREE_SIDE_EFFECTS (se->expr) = 1;
1230 #if 0
1231   if (!sym->attr.pure)
1232     TREE_SIDE_EFFECTS (se->expr) = 1;
1233 #endif
1234
1235   if (byref)
1236     {
1237       /* Add the function call to the pre chain.  There is no expression.  */
1238       gfc_add_expr_to_block (&se->pre, se->expr);
1239       se->expr = NULL_TREE;
1240
1241       if (!se->direct_byref)
1242         {
1243           if (sym->result->attr.dimension)
1244             {
1245               if (flag_bounds_check)
1246                 {
1247                   /* Check the data pointer hasn't been modified.  This would
1248                      happen in a function returning a pointer.  */
1249                   tmp = gfc_conv_descriptor_data (info->descriptor);
1250                   tmp = build2 (NE_EXPR, boolean_type_node, tmp, info->data);
1251                   gfc_trans_runtime_check (tmp, gfc_strconst_fault, &se->pre);
1252                 }
1253               se->expr = info->descriptor;
1254             }
1255           else if (sym->ts.type == BT_CHARACTER)
1256             {
1257               se->expr = var;
1258               se->string_length = len;
1259             }
1260           else
1261             gcc_unreachable ();
1262         }
1263     }
1264 }
1265
1266
1267 /* Generate code to copy a string.  */
1268
1269 static void
1270 gfc_trans_string_copy (stmtblock_t * block, tree dlen, tree dest,
1271                        tree slen, tree src)
1272 {
1273   tree tmp;
1274
1275   tmp = NULL_TREE;
1276   tmp = gfc_chainon_list (tmp, dlen);
1277   tmp = gfc_chainon_list (tmp, dest);
1278   tmp = gfc_chainon_list (tmp, slen);
1279   tmp = gfc_chainon_list (tmp, src);
1280   tmp = gfc_build_function_call (gfor_fndecl_copy_string, tmp);
1281   gfc_add_expr_to_block (block, tmp);
1282 }
1283
1284
1285 /* Translate a statement function.
1286    The value of a statement function reference is obtained by evaluating the
1287    expression using the values of the actual arguments for the values of the
1288    corresponding dummy arguments.  */
1289
1290 static void
1291 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
1292 {
1293   gfc_symbol *sym;
1294   gfc_symbol *fsym;
1295   gfc_formal_arglist *fargs;
1296   gfc_actual_arglist *args;
1297   gfc_se lse;
1298   gfc_se rse;
1299   gfc_saved_var *saved_vars;
1300   tree *temp_vars;
1301   tree type;
1302   tree tmp;
1303   int n;
1304
1305   sym = expr->symtree->n.sym;
1306   args = expr->value.function.actual;
1307   gfc_init_se (&lse, NULL);
1308   gfc_init_se (&rse, NULL);
1309
1310   n = 0;
1311   for (fargs = sym->formal; fargs; fargs = fargs->next)
1312     n++;
1313   saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
1314   temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
1315
1316   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
1317     {
1318       /* Each dummy shall be specified, explicitly or implicitly, to be
1319          scalar.  */
1320       gcc_assert (fargs->sym->attr.dimension == 0);
1321       fsym = fargs->sym;
1322
1323       /* Create a temporary to hold the value.  */
1324       type = gfc_typenode_for_spec (&fsym->ts);
1325       temp_vars[n] = gfc_create_var (type, fsym->name);
1326
1327       if (fsym->ts.type == BT_CHARACTER)
1328         {
1329           /* Copy string arguments.  */
1330           tree arglen;
1331
1332           gcc_assert (fsym->ts.cl && fsym->ts.cl->length
1333                   && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
1334
1335           arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1336           tmp = gfc_build_addr_expr (build_pointer_type (type),
1337                                      temp_vars[n]);
1338
1339           gfc_conv_expr (&rse, args->expr);
1340           gfc_conv_string_parameter (&rse);
1341           gfc_add_block_to_block (&se->pre, &lse.pre);
1342           gfc_add_block_to_block (&se->pre, &rse.pre);
1343
1344           gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
1345                                  rse.expr);
1346           gfc_add_block_to_block (&se->pre, &lse.post);
1347           gfc_add_block_to_block (&se->pre, &rse.post);
1348         }
1349       else
1350         {
1351           /* For everything else, just evaluate the expression.  */
1352           gfc_conv_expr (&lse, args->expr);
1353
1354           gfc_add_block_to_block (&se->pre, &lse.pre);
1355           gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
1356           gfc_add_block_to_block (&se->pre, &lse.post);
1357         }
1358
1359       args = args->next;
1360     }
1361
1362   /* Use the temporary variables in place of the real ones.  */
1363   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
1364     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
1365
1366   gfc_conv_expr (se, sym->value);
1367
1368   if (sym->ts.type == BT_CHARACTER)
1369     {
1370       gfc_conv_const_charlen (sym->ts.cl);
1371
1372       /* Force the expression to the correct length.  */
1373       if (!INTEGER_CST_P (se->string_length)
1374           || tree_int_cst_lt (se->string_length,
1375                               sym->ts.cl->backend_decl))
1376         {
1377           type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
1378           tmp = gfc_create_var (type, sym->name);
1379           tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
1380           gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
1381                                  se->string_length, se->expr);
1382           se->expr = tmp;
1383         }
1384       se->string_length = sym->ts.cl->backend_decl;
1385     }
1386
1387   /* Restore the original variables.  */
1388   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
1389     gfc_restore_sym (fargs->sym, &saved_vars[n]);
1390   gfc_free (saved_vars);
1391 }
1392
1393
1394 /* Translate a function expression.  */
1395
1396 static void
1397 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
1398 {
1399   gfc_symbol *sym;
1400
1401   if (expr->value.function.isym)
1402     {
1403       gfc_conv_intrinsic_function (se, expr);
1404       return;
1405     }
1406
1407   /* We distinguish statement functions from general functions to improve
1408      runtime performance.  */
1409   if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
1410     {
1411       gfc_conv_statement_function (se, expr);
1412       return;
1413     }
1414
1415   /* expr.value.function.esym is the resolved (specific) function symbol for
1416      most functions.  However this isn't set for dummy procedures.  */
1417   sym = expr->value.function.esym;
1418   if (!sym)
1419     sym = expr->symtree->n.sym;
1420   gfc_conv_function_call (se, sym, expr->value.function.actual);
1421 }
1422
1423
1424 static void
1425 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
1426 {
1427   gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
1428   gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
1429
1430   gfc_conv_tmp_array_ref (se);
1431   gfc_advance_se_ss_chain (se);
1432 }
1433
1434
1435 /* Build a static initializer.  EXPR is the expression for the initial value.
1436    The other parameters describe the variable of the component being 
1437    initialized. EXPR may be null.  */
1438
1439 tree
1440 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
1441                       bool array, bool pointer)
1442 {
1443   gfc_se se;
1444
1445   if (!(expr || pointer))
1446     return NULL_TREE;
1447
1448   if (array)
1449     {
1450       /* Arrays need special handling.  */
1451       if (pointer)
1452         return gfc_build_null_descriptor (type);
1453       else
1454         return gfc_conv_array_initializer (type, expr);
1455     }
1456   else if (pointer)
1457     return fold_convert (type, null_pointer_node);
1458   else
1459     {
1460       switch (ts->type)
1461         {
1462         case BT_DERIVED:
1463           gfc_init_se (&se, NULL);
1464           gfc_conv_structure (&se, expr, 1);
1465           return se.expr;
1466
1467         case BT_CHARACTER:
1468           return gfc_conv_string_init (ts->cl->backend_decl,expr);
1469
1470         default:
1471           gfc_init_se (&se, NULL);
1472           gfc_conv_constant (&se, expr);
1473           return se.expr;
1474         }
1475     }
1476 }
1477   
1478 static tree
1479 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
1480 {
1481   gfc_se rse;
1482   gfc_se lse;
1483   gfc_ss *rss;
1484   gfc_ss *lss;
1485   stmtblock_t body;
1486   stmtblock_t block;
1487   gfc_loopinfo loop;
1488   int n;
1489   tree tmp;
1490
1491   gfc_start_block (&block);
1492
1493   /* Initialize the scalarizer.  */
1494   gfc_init_loopinfo (&loop);
1495
1496   gfc_init_se (&lse, NULL);
1497   gfc_init_se (&rse, NULL);
1498
1499   /* Walk the rhs.  */
1500   rss = gfc_walk_expr (expr);
1501   if (rss == gfc_ss_terminator)
1502     {
1503       /* The rhs is scalar.  Add a ss for the expression.  */
1504       rss = gfc_get_ss ();
1505       rss->next = gfc_ss_terminator;
1506       rss->type = GFC_SS_SCALAR;
1507       rss->expr = expr;
1508     }
1509
1510   /* Create a SS for the destination.  */
1511   lss = gfc_get_ss ();
1512   lss->type = GFC_SS_COMPONENT;
1513   lss->expr = NULL;
1514   lss->shape = gfc_get_shape (cm->as->rank);
1515   lss->next = gfc_ss_terminator;
1516   lss->data.info.dimen = cm->as->rank;
1517   lss->data.info.descriptor = dest;
1518   lss->data.info.data = gfc_conv_array_data (dest);
1519   lss->data.info.offset = gfc_conv_array_offset (dest);
1520   for (n = 0; n < cm->as->rank; n++)
1521     {
1522       lss->data.info.dim[n] = n;
1523       lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
1524       lss->data.info.stride[n] = gfc_index_one_node;
1525
1526       mpz_init (lss->shape[n]);
1527       mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
1528                cm->as->lower[n]->value.integer);
1529       mpz_add_ui (lss->shape[n], lss->shape[n], 1);
1530     }
1531   
1532   /* Associate the SS with the loop.  */
1533   gfc_add_ss_to_loop (&loop, lss);
1534   gfc_add_ss_to_loop (&loop, rss);
1535
1536   /* Calculate the bounds of the scalarization.  */
1537   gfc_conv_ss_startstride (&loop);
1538
1539   /* Setup the scalarizing loops.  */
1540   gfc_conv_loop_setup (&loop);
1541
1542   /* Setup the gfc_se structures.  */
1543   gfc_copy_loopinfo_to_se (&lse, &loop);
1544   gfc_copy_loopinfo_to_se (&rse, &loop);
1545
1546   rse.ss = rss;
1547   gfc_mark_ss_chain_used (rss, 1);
1548   lse.ss = lss;
1549   gfc_mark_ss_chain_used (lss, 1);
1550
1551   /* Start the scalarized loop body.  */
1552   gfc_start_scalarized_body (&loop, &body);
1553
1554   gfc_conv_tmp_array_ref (&lse);
1555   gfc_conv_expr (&rse, expr);
1556
1557   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts.type);
1558   gfc_add_expr_to_block (&body, tmp);
1559
1560   gcc_assert (rse.ss == gfc_ss_terminator);
1561
1562   /* Generate the copying loops.  */
1563   gfc_trans_scalarizing_loops (&loop, &body);
1564
1565   /* Wrap the whole thing up.  */
1566   gfc_add_block_to_block (&block, &loop.pre);
1567   gfc_add_block_to_block (&block, &loop.post);
1568
1569   for (n = 0; n < cm->as->rank; n++)
1570     mpz_clear (lss->shape[n]);
1571   gfc_free (lss->shape);
1572
1573   gfc_cleanup_loop (&loop);
1574
1575   return gfc_finish_block (&block);
1576 }
1577
1578 /* Assign a single component of a derived type constructor.  */
1579
1580 static tree
1581 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
1582 {
1583   gfc_se se;
1584   gfc_ss *rss;
1585   stmtblock_t block;
1586   tree tmp;
1587
1588   gfc_start_block (&block);
1589   if (cm->pointer)
1590     {
1591       gfc_init_se (&se, NULL);
1592       /* Pointer component.  */
1593       if (cm->dimension)
1594         {
1595           /* Array pointer.  */
1596           if (expr->expr_type == EXPR_NULL)
1597             {
1598               dest = gfc_conv_descriptor_data (dest);
1599               tmp = fold_convert (TREE_TYPE (se.expr),
1600                                   null_pointer_node);
1601               gfc_add_modify_expr (&block, dest, tmp);
1602             }
1603           else
1604             {
1605               rss = gfc_walk_expr (expr);
1606               se.direct_byref = 1;
1607               se.expr = dest;
1608               gfc_conv_expr_descriptor (&se, expr, rss);
1609               gfc_add_block_to_block (&block, &se.pre);
1610               gfc_add_block_to_block (&block, &se.post);
1611             }
1612         }
1613       else
1614         {
1615           /* Scalar pointers.  */
1616           se.want_pointer = 1;
1617           gfc_conv_expr (&se, expr);
1618           gfc_add_block_to_block (&block, &se.pre);
1619           gfc_add_modify_expr (&block, dest,
1620                                fold_convert (TREE_TYPE (dest), se.expr));
1621           gfc_add_block_to_block (&block, &se.post);
1622         }
1623     }
1624   else if (cm->dimension)
1625     {
1626       tmp = gfc_trans_subarray_assign (dest, cm, expr);
1627       gfc_add_expr_to_block (&block, tmp);
1628     }
1629   else if (expr->ts.type == BT_DERIVED)
1630     {
1631       /* Nested derived type.  */
1632       tmp = gfc_trans_structure_assign (dest, expr);
1633       gfc_add_expr_to_block (&block, tmp);
1634     }
1635   else
1636     {
1637       /* Scalar component.  */
1638       gfc_se lse;
1639
1640       gfc_init_se (&se, NULL);
1641       gfc_init_se (&lse, NULL);
1642
1643       gfc_conv_expr (&se, expr);
1644       if (cm->ts.type == BT_CHARACTER)
1645         lse.string_length = cm->ts.cl->backend_decl;
1646       lse.expr = dest;
1647       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts.type);
1648       gfc_add_expr_to_block (&block, tmp);
1649     }
1650   return gfc_finish_block (&block);
1651 }
1652
1653 /* Assign a derived type constructor to a variable.  */
1654
1655 static tree
1656 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
1657 {
1658   gfc_constructor *c;
1659   gfc_component *cm;
1660   stmtblock_t block;
1661   tree field;
1662   tree tmp;
1663
1664   gfc_start_block (&block);
1665   cm = expr->ts.derived->components;
1666   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
1667     {
1668       /* Skip absent members in default initializers.  */
1669       if (!c->expr)
1670         continue;
1671
1672       field = cm->backend_decl;
1673       tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
1674       tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
1675       gfc_add_expr_to_block (&block, tmp);
1676     }
1677   return gfc_finish_block (&block);
1678 }
1679
1680 /* Build an expression for a constructor. If init is nonzero then
1681    this is part of a static variable initializer.  */
1682
1683 void
1684 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
1685 {
1686   gfc_constructor *c;
1687   gfc_component *cm;
1688   tree head;
1689   tree tail;
1690   tree val;
1691   tree type;
1692   tree tmp;
1693
1694   gcc_assert (se->ss == NULL);
1695   gcc_assert (expr->expr_type == EXPR_STRUCTURE);
1696   type = gfc_typenode_for_spec (&expr->ts);
1697
1698   if (!init)
1699     {
1700       /* Create a temporary variable and fill it in.  */
1701       se->expr = gfc_create_var (type, expr->ts.derived->name);
1702       tmp = gfc_trans_structure_assign (se->expr, expr);
1703       gfc_add_expr_to_block (&se->pre, tmp);
1704       return;
1705     }
1706
1707   head = build1 (CONSTRUCTOR, type, NULL_TREE);
1708   tail = NULL_TREE;
1709
1710   cm = expr->ts.derived->components;
1711   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
1712     {
1713       /* Skip absent members in default initializers.  */
1714       if (!c->expr)
1715         continue;
1716
1717       val = gfc_conv_initializer (c->expr, &cm->ts,
1718           TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
1719
1720       /* Build a TREE_CHAIN to hold it.  */
1721       val = tree_cons (cm->backend_decl, val, NULL_TREE);
1722
1723       /* Add it to the list.  */
1724       if (tail == NULL_TREE)
1725         TREE_OPERAND(head, 0) = tail = val;
1726       else
1727         {
1728           TREE_CHAIN (tail) = val;
1729           tail = val;
1730         }
1731     }
1732   se->expr = head;
1733 }
1734
1735
1736 /* Translate a substring expression.  */
1737
1738 static void
1739 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
1740 {
1741   gfc_ref *ref;
1742
1743   ref = expr->ref;
1744
1745   gcc_assert (ref->type == REF_SUBSTRING);
1746
1747   se->expr = gfc_build_string_const(expr->value.character.length,
1748                                     expr->value.character.string);
1749   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
1750   TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
1751
1752   gfc_conv_substring(se,ref,expr->ts.kind);
1753 }
1754
1755
1756 /* Entry point for expression translation.  */
1757
1758 void
1759 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
1760 {
1761   if (se->ss && se->ss->expr == expr
1762       && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
1763     {
1764       /* Substitute a scalar expression evaluated outside the scalarization
1765          loop.  */
1766       se->expr = se->ss->data.scalar.expr;
1767       se->string_length = se->ss->string_length;
1768       gfc_advance_se_ss_chain (se);
1769       return;
1770     }
1771
1772   switch (expr->expr_type)
1773     {
1774     case EXPR_OP:
1775       gfc_conv_expr_op (se, expr);
1776       break;
1777
1778     case EXPR_FUNCTION:
1779       gfc_conv_function_expr (se, expr);
1780       break;
1781
1782     case EXPR_CONSTANT:
1783       gfc_conv_constant (se, expr);
1784       break;
1785
1786     case EXPR_VARIABLE:
1787       gfc_conv_variable (se, expr);
1788       break;
1789
1790     case EXPR_NULL:
1791       se->expr = null_pointer_node;
1792       break;
1793
1794     case EXPR_SUBSTRING:
1795       gfc_conv_substring_expr (se, expr);
1796       break;
1797
1798     case EXPR_STRUCTURE:
1799       gfc_conv_structure (se, expr, 0);
1800       break;
1801
1802     case EXPR_ARRAY:
1803       gfc_conv_array_constructor_expr (se, expr);
1804       break;
1805
1806     default:
1807       gcc_unreachable ();
1808       break;
1809     }
1810 }
1811
1812 void
1813 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
1814 {
1815   gfc_conv_expr (se, expr);
1816   /* AFAICS all numeric lvalues have empty post chains.  If not we need to
1817      figure out a way of rewriting an lvalue so that it has no post chain.  */
1818   gcc_assert (expr->ts.type != BT_CHARACTER || !se->post.head);
1819 }
1820
1821 void
1822 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
1823 {
1824   tree val;
1825
1826   gcc_assert (expr->ts.type != BT_CHARACTER);
1827   gfc_conv_expr (se, expr);
1828   if (se->post.head)
1829     {
1830       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
1831       gfc_add_modify_expr (&se->pre, val, se->expr);
1832     }
1833 }
1834
1835 void
1836 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
1837 {
1838   gfc_conv_expr_val (se, expr);
1839   se->expr = convert (type, se->expr);
1840 }
1841
1842
1843 /* Converts an expression so that it can be passed by reference.  Scalar
1844    values only.  */
1845
1846 void
1847 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
1848 {
1849   tree var;
1850
1851   if (se->ss && se->ss->expr == expr
1852       && se->ss->type == GFC_SS_REFERENCE)
1853     {
1854       se->expr = se->ss->data.scalar.expr;
1855       se->string_length = se->ss->string_length;
1856       gfc_advance_se_ss_chain (se);
1857       return;
1858     }
1859
1860   if (expr->ts.type == BT_CHARACTER)
1861     {
1862       gfc_conv_expr (se, expr);
1863       gfc_conv_string_parameter (se);
1864       return;
1865     }
1866
1867   if (expr->expr_type == EXPR_VARIABLE)
1868     {
1869       se->want_pointer = 1;
1870       gfc_conv_expr (se, expr);
1871       if (se->post.head)
1872         {
1873           var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1874           gfc_add_modify_expr (&se->pre, var, se->expr);
1875           gfc_add_block_to_block (&se->pre, &se->post);
1876           se->expr = var;
1877         }
1878       return;
1879     }
1880
1881   gfc_conv_expr (se, expr);
1882
1883   /* Create a temporary var to hold the value.  */
1884   if (TREE_CONSTANT (se->expr))
1885     {
1886       var = build_decl (CONST_DECL, NULL, TREE_TYPE (se->expr));
1887       DECL_INITIAL (var) = se->expr;
1888       pushdecl (var);
1889     }
1890   else
1891     {
1892       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1893       gfc_add_modify_expr (&se->pre, var, se->expr);
1894     }
1895   gfc_add_block_to_block (&se->pre, &se->post);
1896
1897   /* Take the address of that value.  */
1898   se->expr = gfc_build_addr_expr (NULL, var);
1899 }
1900
1901
1902 tree
1903 gfc_trans_pointer_assign (gfc_code * code)
1904 {
1905   return gfc_trans_pointer_assignment (code->expr, code->expr2);
1906 }
1907
1908
1909 /* Generate code for a pointer assignment.  */
1910
1911 tree
1912 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
1913 {
1914   gfc_se lse;
1915   gfc_se rse;
1916   gfc_ss *lss;
1917   gfc_ss *rss;
1918   stmtblock_t block;
1919
1920   gfc_start_block (&block);
1921
1922   gfc_init_se (&lse, NULL);
1923
1924   lss = gfc_walk_expr (expr1);
1925   rss = gfc_walk_expr (expr2);
1926   if (lss == gfc_ss_terminator)
1927     {
1928       /* Scalar pointers.  */
1929       lse.want_pointer = 1;
1930       gfc_conv_expr (&lse, expr1);
1931       gcc_assert (rss == gfc_ss_terminator);
1932       gfc_init_se (&rse, NULL);
1933       rse.want_pointer = 1;
1934       gfc_conv_expr (&rse, expr2);
1935       gfc_add_block_to_block (&block, &lse.pre);
1936       gfc_add_block_to_block (&block, &rse.pre);
1937       gfc_add_modify_expr (&block, lse.expr,
1938                            fold_convert (TREE_TYPE (lse.expr), rse.expr));
1939       gfc_add_block_to_block (&block, &rse.post);
1940       gfc_add_block_to_block (&block, &lse.post);
1941     }
1942   else
1943     {
1944       /* Array pointer.  */
1945       gfc_conv_expr_descriptor (&lse, expr1, lss);
1946       /* Implement Nullify.  */
1947       if (expr2->expr_type == EXPR_NULL)
1948         {
1949           lse.expr = gfc_conv_descriptor_data (lse.expr);
1950           rse.expr = fold_convert (TREE_TYPE (lse.expr), null_pointer_node);
1951           gfc_add_modify_expr (&block, lse.expr, rse.expr);
1952         }
1953       else
1954         {
1955           lse.direct_byref = 1;
1956           gfc_conv_expr_descriptor (&lse, expr2, rss);
1957         }
1958       gfc_add_block_to_block (&block, &lse.pre);
1959       gfc_add_block_to_block (&block, &lse.post);
1960     }
1961   return gfc_finish_block (&block);
1962 }
1963
1964
1965 /* Makes sure se is suitable for passing as a function string parameter.  */
1966 /* TODO: Need to check all callers fo this function.  It may be abused.  */
1967
1968 void
1969 gfc_conv_string_parameter (gfc_se * se)
1970 {
1971   tree type;
1972
1973   if (TREE_CODE (se->expr) == STRING_CST)
1974     {
1975       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
1976       return;
1977     }
1978
1979   type = TREE_TYPE (se->expr);
1980   if (TYPE_STRING_FLAG (type))
1981     {
1982       gcc_assert (TREE_CODE (se->expr) != INDIRECT_REF);
1983       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
1984     }
1985
1986   gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
1987   gcc_assert (se->string_length
1988           && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
1989 }
1990
1991
1992 /* Generate code for assignment of scalar variables.  Includes character
1993    strings.  */
1994
1995 tree
1996 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, bt type)
1997 {
1998   stmtblock_t block;
1999
2000   gfc_init_block (&block);
2001
2002   if (type == BT_CHARACTER)
2003     {
2004       gcc_assert (lse->string_length != NULL_TREE
2005               && rse->string_length != NULL_TREE);
2006
2007       gfc_conv_string_parameter (lse);
2008       gfc_conv_string_parameter (rse);
2009
2010       gfc_add_block_to_block (&block, &lse->pre);
2011       gfc_add_block_to_block (&block, &rse->pre);
2012
2013       gfc_trans_string_copy (&block, lse->string_length, lse->expr,
2014                              rse->string_length, rse->expr);
2015     }
2016   else
2017     {
2018       gfc_add_block_to_block (&block, &lse->pre);
2019       gfc_add_block_to_block (&block, &rse->pre);
2020
2021       gfc_add_modify_expr (&block, lse->expr,
2022                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
2023     }
2024
2025   gfc_add_block_to_block (&block, &lse->post);
2026   gfc_add_block_to_block (&block, &rse->post);
2027
2028   return gfc_finish_block (&block);
2029 }
2030
2031
2032 /* Try to translate array(:) = func (...), where func is a transformational
2033    array function, without using a temporary.  Returns NULL is this isn't the
2034    case.  */
2035
2036 static tree
2037 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
2038 {
2039   gfc_se se;
2040   gfc_ss *ss;
2041
2042   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
2043   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
2044     return NULL;
2045
2046   /* Elemental functions don't need a temporary anyway.  */
2047   if (expr2->symtree->n.sym->attr.elemental)
2048     return NULL;
2049
2050   /* Check for a dependency.  */
2051   if (gfc_check_fncall_dependency (expr1, expr2))
2052     return NULL;
2053
2054   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
2055      functions.  */
2056   gcc_assert (expr2->value.function.isym
2057               || (gfc_return_by_reference (expr2->value.function.esym)
2058               && expr2->value.function.esym->result->attr.dimension));
2059
2060   ss = gfc_walk_expr (expr1);
2061   gcc_assert (ss != gfc_ss_terminator);
2062   gfc_init_se (&se, NULL);
2063   gfc_start_block (&se.pre);
2064   se.want_pointer = 1;
2065
2066   gfc_conv_array_parameter (&se, expr1, ss, 0);
2067
2068   se.direct_byref = 1;
2069   se.ss = gfc_walk_expr (expr2);
2070   gcc_assert (se.ss != gfc_ss_terminator);
2071   gfc_conv_function_expr (&se, expr2);
2072   gfc_add_block_to_block (&se.pre, &se.post);
2073
2074   return gfc_finish_block (&se.pre);
2075 }
2076
2077
2078 /* Translate an assignment.  Most of the code is concerned with
2079    setting up the scalarizer.  */
2080
2081 tree
2082 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2)
2083 {
2084   gfc_se lse;
2085   gfc_se rse;
2086   gfc_ss *lss;
2087   gfc_ss *lss_section;
2088   gfc_ss *rss;
2089   gfc_loopinfo loop;
2090   tree tmp;
2091   stmtblock_t block;
2092   stmtblock_t body;
2093
2094   /* Special case a single function returning an array.  */
2095   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
2096     {
2097       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
2098       if (tmp)
2099         return tmp;
2100     }
2101
2102   /* Assignment of the form lhs = rhs.  */
2103   gfc_start_block (&block);
2104
2105   gfc_init_se (&lse, NULL);
2106   gfc_init_se (&rse, NULL);
2107
2108   /* Walk the lhs.  */
2109   lss = gfc_walk_expr (expr1);
2110   rss = NULL;
2111   if (lss != gfc_ss_terminator)
2112     {
2113       /* The assignment needs scalarization.  */
2114       lss_section = lss;
2115
2116       /* Find a non-scalar SS from the lhs.  */
2117       while (lss_section != gfc_ss_terminator
2118              && lss_section->type != GFC_SS_SECTION)
2119         lss_section = lss_section->next;
2120
2121       gcc_assert (lss_section != gfc_ss_terminator);
2122
2123       /* Initialize the scalarizer.  */
2124       gfc_init_loopinfo (&loop);
2125
2126       /* Walk the rhs.  */
2127       rss = gfc_walk_expr (expr2);
2128       if (rss == gfc_ss_terminator)
2129         {
2130           /* The rhs is scalar.  Add a ss for the expression.  */
2131           rss = gfc_get_ss ();
2132           rss->next = gfc_ss_terminator;
2133           rss->type = GFC_SS_SCALAR;
2134           rss->expr = expr2;
2135         }
2136       /* Associate the SS with the loop.  */
2137       gfc_add_ss_to_loop (&loop, lss);
2138       gfc_add_ss_to_loop (&loop, rss);
2139
2140       /* Calculate the bounds of the scalarization.  */
2141       gfc_conv_ss_startstride (&loop);
2142       /* Resolve any data dependencies in the statement.  */
2143       gfc_conv_resolve_dependencies (&loop, lss_section, rss);
2144       /* Setup the scalarizing loops.  */
2145       gfc_conv_loop_setup (&loop);
2146
2147       /* Setup the gfc_se structures.  */
2148       gfc_copy_loopinfo_to_se (&lse, &loop);
2149       gfc_copy_loopinfo_to_se (&rse, &loop);
2150
2151       rse.ss = rss;
2152       gfc_mark_ss_chain_used (rss, 1);
2153       if (loop.temp_ss == NULL)
2154         {
2155           lse.ss = lss;
2156           gfc_mark_ss_chain_used (lss, 1);
2157         }
2158       else
2159         {
2160           lse.ss = loop.temp_ss;
2161           gfc_mark_ss_chain_used (lss, 3);
2162           gfc_mark_ss_chain_used (loop.temp_ss, 3);
2163         }
2164
2165       /* Start the scalarized loop body.  */
2166       gfc_start_scalarized_body (&loop, &body);
2167     }
2168   else
2169     gfc_init_block (&body);
2170
2171   /* Translate the expression.  */
2172   gfc_conv_expr (&rse, expr2);
2173
2174   if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
2175     {
2176       gfc_conv_tmp_array_ref (&lse);
2177       gfc_advance_se_ss_chain (&lse);
2178     }
2179   else
2180     gfc_conv_expr (&lse, expr1);
2181
2182   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2183   gfc_add_expr_to_block (&body, tmp);
2184
2185   if (lss == gfc_ss_terminator)
2186     {
2187       /* Use the scalar assignment as is.  */
2188       gfc_add_block_to_block (&block, &body);
2189     }
2190   else
2191     {
2192       gcc_assert (lse.ss == gfc_ss_terminator
2193                   && rse.ss == gfc_ss_terminator);
2194
2195       if (loop.temp_ss != NULL)
2196         {
2197           gfc_trans_scalarized_loop_boundary (&loop, &body);
2198
2199           /* We need to copy the temporary to the actual lhs.  */
2200           gfc_init_se (&lse, NULL);
2201           gfc_init_se (&rse, NULL);
2202           gfc_copy_loopinfo_to_se (&lse, &loop);
2203           gfc_copy_loopinfo_to_se (&rse, &loop);
2204
2205           rse.ss = loop.temp_ss;
2206           lse.ss = lss;
2207
2208           gfc_conv_tmp_array_ref (&rse);
2209           gfc_advance_se_ss_chain (&rse);
2210           gfc_conv_expr (&lse, expr1);
2211
2212           gcc_assert (lse.ss == gfc_ss_terminator
2213                       && rse.ss == gfc_ss_terminator);
2214
2215           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2216           gfc_add_expr_to_block (&body, tmp);
2217         }
2218       /* Generate the copying loops.  */
2219       gfc_trans_scalarizing_loops (&loop, &body);
2220
2221       /* Wrap the whole thing up.  */
2222       gfc_add_block_to_block (&block, &loop.pre);
2223       gfc_add_block_to_block (&block, &loop.post);
2224
2225       gfc_cleanup_loop (&loop);
2226     }
2227
2228   return gfc_finish_block (&block);
2229 }
2230
2231 tree
2232 gfc_trans_assign (gfc_code * code)
2233 {
2234   return gfc_trans_assignment (code->expr, code->expr2);
2235 }