OSDN Git Service

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