OSDN Git Service

2009-10-29 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-expr.c
1 /* Expression translation
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3    Free Software Foundation, Inc.
4    Contributed by Paul Brook <paul@nowt.org>
5    and Steven Bosscher <s.bosscher@student.tudelft.nl>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 /* trans-expr.c-- generate GENERIC trees for gfc_expr.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tree.h"
29 #include "convert.h"
30 #include "ggc.h"
31 #include "toplev.h"
32 #include "real.h"
33 #include "gimple.h"
34 #include "langhooks.h"
35 #include "flags.h"
36 #include "gfortran.h"
37 #include "arith.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 #include "dependency.h"
45
46 static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
47 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
48                                                  gfc_expr *);
49
50 /* Copy the scalarization loop variables.  */
51
52 static void
53 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
54 {
55   dest->ss = src->ss;
56   dest->loop = src->loop;
57 }
58
59
60 /* Initialize a simple expression holder.
61
62    Care must be taken when multiple se are created with the same parent.
63    The child se must be kept in sync.  The easiest way is to delay creation
64    of a child se until after after the previous se has been translated.  */
65
66 void
67 gfc_init_se (gfc_se * se, gfc_se * parent)
68 {
69   memset (se, 0, sizeof (gfc_se));
70   gfc_init_block (&se->pre);
71   gfc_init_block (&se->post);
72
73   se->parent = parent;
74
75   if (parent)
76     gfc_copy_se_loopvars (se, parent);
77 }
78
79
80 /* Advances to the next SS in the chain.  Use this rather than setting
81    se->ss = se->ss->next because all the parents needs to be kept in sync.
82    See gfc_init_se.  */
83
84 void
85 gfc_advance_se_ss_chain (gfc_se * se)
86 {
87   gfc_se *p;
88
89   gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
90
91   p = se;
92   /* Walk down the parent chain.  */
93   while (p != NULL)
94     {
95       /* Simple consistency check.  */
96       gcc_assert (p->parent == NULL || p->parent->ss == p->ss);
97
98       p->ss = p->ss->next;
99
100       p = p->parent;
101     }
102 }
103
104
105 /* Ensures the result of the expression as either a temporary variable
106    or a constant so that it can be used repeatedly.  */
107
108 void
109 gfc_make_safe_expr (gfc_se * se)
110 {
111   tree var;
112
113   if (CONSTANT_CLASS_P (se->expr))
114     return;
115
116   /* We need a temporary for this result.  */
117   var = gfc_create_var (TREE_TYPE (se->expr), NULL);
118   gfc_add_modify (&se->pre, var, se->expr);
119   se->expr = var;
120 }
121
122
123 /* Return an expression which determines if a dummy parameter is present.
124    Also used for arguments to procedures with multiple entry points.  */
125
126 tree
127 gfc_conv_expr_present (gfc_symbol * sym)
128 {
129   tree decl;
130
131   gcc_assert (sym->attr.dummy);
132
133   decl = gfc_get_symbol_decl (sym);
134   if (TREE_CODE (decl) != PARM_DECL)
135     {
136       /* Array parameters use a temporary descriptor, we want the real
137          parameter.  */
138       gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
139              || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
140       decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
141     }
142   return fold_build2 (NE_EXPR, boolean_type_node, decl,
143                       fold_convert (TREE_TYPE (decl), null_pointer_node));
144 }
145
146
147 /* Converts a missing, dummy argument into a null or zero.  */
148
149 void
150 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
151 {
152   tree present;
153   tree tmp;
154
155   present = gfc_conv_expr_present (arg->symtree->n.sym);
156
157   if (kind > 0)
158     {
159       /* Create a temporary and convert it to the correct type.  */
160       tmp = gfc_get_int_type (kind);
161       tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
162                                                         se->expr));
163     
164       /* Test for a NULL value.  */
165       tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present, tmp,
166                     fold_convert (TREE_TYPE (tmp), integer_one_node));
167       tmp = gfc_evaluate_now (tmp, &se->pre);
168       se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
169     }
170   else
171     {
172       tmp = build3 (COND_EXPR, TREE_TYPE (se->expr), present, se->expr,
173                     fold_convert (TREE_TYPE (se->expr), integer_zero_node));
174       tmp = gfc_evaluate_now (tmp, &se->pre);
175       se->expr = tmp;
176     }
177
178   if (ts.type == BT_CHARACTER)
179     {
180       tmp = build_int_cst (gfc_charlen_type_node, 0);
181       tmp = fold_build3 (COND_EXPR, gfc_charlen_type_node,
182                          present, se->string_length, tmp);
183       tmp = gfc_evaluate_now (tmp, &se->pre);
184       se->string_length = tmp;
185     }
186   return;
187 }
188
189
190 /* Get the character length of an expression, looking through gfc_refs
191    if necessary.  */
192
193 tree
194 gfc_get_expr_charlen (gfc_expr *e)
195 {
196   gfc_ref *r;
197   tree length;
198
199   gcc_assert (e->expr_type == EXPR_VARIABLE 
200               && e->ts.type == BT_CHARACTER);
201   
202   length = NULL; /* To silence compiler warning.  */
203
204   if (is_subref_array (e) && e->ts.u.cl->length)
205     {
206       gfc_se tmpse;
207       gfc_init_se (&tmpse, NULL);
208       gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
209       e->ts.u.cl->backend_decl = tmpse.expr;
210       return tmpse.expr;
211     }
212
213   /* First candidate: if the variable is of type CHARACTER, the
214      expression's length could be the length of the character
215      variable.  */
216   if (e->symtree->n.sym->ts.type == BT_CHARACTER)
217     length = e->symtree->n.sym->ts.u.cl->backend_decl;
218
219   /* Look through the reference chain for component references.  */
220   for (r = e->ref; r; r = r->next)
221     {
222       switch (r->type)
223         {
224         case REF_COMPONENT:
225           if (r->u.c.component->ts.type == BT_CHARACTER)
226             length = r->u.c.component->ts.u.cl->backend_decl;
227           break;
228
229         case REF_ARRAY:
230           /* Do nothing.  */
231           break;
232
233         default:
234           /* We should never got substring references here.  These will be
235              broken down by the scalarizer.  */
236           gcc_unreachable ();
237           break;
238         }
239     }
240
241   gcc_assert (length != NULL);
242   return length;
243 }
244
245
246 /* For each character array constructor subexpression without a ts.u.cl->length,
247    replace it by its first element (if there aren't any elements, the length
248    should already be set to zero).  */
249
250 static void
251 flatten_array_ctors_without_strlen (gfc_expr* e)
252 {
253   gfc_actual_arglist* arg;
254   gfc_constructor* c;
255
256   if (!e)
257     return;
258
259   switch (e->expr_type)
260     {
261
262     case EXPR_OP:
263       flatten_array_ctors_without_strlen (e->value.op.op1); 
264       flatten_array_ctors_without_strlen (e->value.op.op2); 
265       break;
266
267     case EXPR_COMPCALL:
268       /* TODO: Implement as with EXPR_FUNCTION when needed.  */
269       gcc_unreachable ();
270
271     case EXPR_FUNCTION:
272       for (arg = e->value.function.actual; arg; arg = arg->next)
273         flatten_array_ctors_without_strlen (arg->expr);
274       break;
275
276     case EXPR_ARRAY:
277
278       /* We've found what we're looking for.  */
279       if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
280         {
281           gfc_expr* new_expr;
282           gcc_assert (e->value.constructor);
283
284           new_expr = e->value.constructor->expr;
285           e->value.constructor->expr = NULL;
286
287           flatten_array_ctors_without_strlen (new_expr);
288           gfc_replace_expr (e, new_expr);
289           break;
290         }
291
292       /* Otherwise, fall through to handle constructor elements.  */
293     case EXPR_STRUCTURE:
294       for (c = e->value.constructor; c; c = c->next)
295         flatten_array_ctors_without_strlen (c->expr);
296       break;
297
298     default:
299       break;
300
301     }
302 }
303
304
305 /* Generate code to initialize a string length variable. Returns the
306    value.  For array constructors, cl->length might be NULL and in this case,
307    the first element of the constructor is needed.  expr is the original
308    expression so we can access it but can be NULL if this is not needed.  */
309
310 void
311 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
312 {
313   gfc_se se;
314
315   gfc_init_se (&se, NULL);
316
317   /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
318      "flatten" array constructors by taking their first element; all elements
319      should be the same length or a cl->length should be present.  */
320   if (!cl->length)
321     {
322       gfc_expr* expr_flat;
323       gcc_assert (expr);
324
325       expr_flat = gfc_copy_expr (expr);
326       flatten_array_ctors_without_strlen (expr_flat);
327       gfc_resolve_expr (expr_flat);
328
329       gfc_conv_expr (&se, expr_flat);
330       gfc_add_block_to_block (pblock, &se.pre);
331       cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
332
333       gfc_free_expr (expr_flat);
334       return;
335     }
336
337   /* Convert cl->length.  */
338
339   gcc_assert (cl->length);
340
341   gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
342   se.expr = fold_build2 (MAX_EXPR, gfc_charlen_type_node, se.expr,
343                          build_int_cst (gfc_charlen_type_node, 0));
344   gfc_add_block_to_block (pblock, &se.pre);
345
346   if (cl->backend_decl)
347     gfc_add_modify (pblock, cl->backend_decl, se.expr);
348   else
349     cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
350 }
351
352
353 static void
354 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
355                     const char *name, locus *where)
356 {
357   tree tmp;
358   tree type;
359   tree var;
360   tree fault;
361   gfc_se start;
362   gfc_se end;
363   char *msg;
364
365   type = gfc_get_character_type (kind, ref->u.ss.length);
366   type = build_pointer_type (type);
367
368   var = NULL_TREE;
369   gfc_init_se (&start, se);
370   gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
371   gfc_add_block_to_block (&se->pre, &start.pre);
372
373   if (integer_onep (start.expr))
374     gfc_conv_string_parameter (se);
375   else
376     {
377       tmp = start.expr;
378       STRIP_NOPS (tmp);
379       /* Avoid multiple evaluation of substring start.  */
380       if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
381         start.expr = gfc_evaluate_now (start.expr, &se->pre);
382
383       /* Change the start of the string.  */
384       if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
385         tmp = se->expr;
386       else
387         tmp = build_fold_indirect_ref_loc (input_location,
388                                        se->expr);
389       tmp = gfc_build_array_ref (tmp, start.expr, NULL);
390       se->expr = gfc_build_addr_expr (type, tmp);
391     }
392
393   /* Length = end + 1 - start.  */
394   gfc_init_se (&end, se);
395   if (ref->u.ss.end == NULL)
396     end.expr = se->string_length;
397   else
398     {
399       gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
400       gfc_add_block_to_block (&se->pre, &end.pre);
401     }
402   tmp = end.expr;
403   STRIP_NOPS (tmp);
404   if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
405     end.expr = gfc_evaluate_now (end.expr, &se->pre);
406
407   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
408     {
409       tree nonempty = fold_build2 (LE_EXPR, boolean_type_node,
410                                    start.expr, end.expr);
411
412       /* Check lower bound.  */
413       fault = fold_build2 (LT_EXPR, boolean_type_node, start.expr,
414                            build_int_cst (gfc_charlen_type_node, 1));
415       fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
416                            nonempty, fault);
417       if (name)
418         asprintf (&msg, "Substring out of bounds: lower bound (%%ld) of '%s' "
419                   "is less than one", name);
420       else
421         asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
422                   "is less than one");
423       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
424                                fold_convert (long_integer_type_node,
425                                              start.expr));
426       gfc_free (msg);
427
428       /* Check upper bound.  */
429       fault = fold_build2 (GT_EXPR, boolean_type_node, end.expr,
430                            se->string_length);
431       fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
432                            nonempty, fault);
433       if (name)
434         asprintf (&msg, "Substring out of bounds: upper bound (%%ld) of '%s' "
435                   "exceeds string length (%%ld)", name);
436       else
437         asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
438                   "exceeds string length (%%ld)");
439       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
440                                fold_convert (long_integer_type_node, end.expr),
441                                fold_convert (long_integer_type_node,
442                                              se->string_length));
443       gfc_free (msg);
444     }
445
446   tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node,
447                      end.expr, start.expr);
448   tmp = fold_build2 (PLUS_EXPR, gfc_charlen_type_node,
449                      build_int_cst (gfc_charlen_type_node, 1), tmp);
450   tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
451                      build_int_cst (gfc_charlen_type_node, 0));
452   se->string_length = tmp;
453 }
454
455
456 /* Convert a derived type component reference.  */
457
458 static void
459 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
460 {
461   gfc_component *c;
462   tree tmp;
463   tree decl;
464   tree field;
465
466   c = ref->u.c.component;
467
468   gcc_assert (c->backend_decl);
469
470   field = c->backend_decl;
471   gcc_assert (TREE_CODE (field) == FIELD_DECL);
472   decl = se->expr;
473   tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
474
475   se->expr = tmp;
476
477   if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer)
478     {
479       tmp = c->ts.u.cl->backend_decl;
480       /* Components must always be constant length.  */
481       gcc_assert (tmp && INTEGER_CST_P (tmp));
482       se->string_length = tmp;
483     }
484
485   if (((c->attr.pointer || c->attr.allocatable) && c->attr.dimension == 0
486        && c->ts.type != BT_CHARACTER)
487       || c->attr.proc_pointer)
488     se->expr = build_fold_indirect_ref_loc (input_location,
489                                         se->expr);
490 }
491
492
493 /* This function deals with component references to components of the
494    parent type for derived type extensons.  */
495 static void
496 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
497 {
498   gfc_component *c;
499   gfc_component *cmp;
500   gfc_symbol *dt;
501   gfc_ref parent;
502
503   dt = ref->u.c.sym;
504   c = ref->u.c.component;
505
506   /* Build a gfc_ref to recursively call gfc_conv_component_ref.  */
507   parent.type = REF_COMPONENT;
508   parent.next = NULL;
509   parent.u.c.sym = dt;
510   parent.u.c.component = dt->components;
511
512   if (dt->attr.extension && dt->components)
513     {
514       if (dt->attr.is_class)
515         cmp = dt->components;
516       else
517         cmp = dt->components->next;
518       /* Return if the component is not in the parent type.  */
519       for (; cmp; cmp = cmp->next)
520         if (strcmp (c->name, cmp->name) == 0)
521           return;
522         
523       /* Otherwise build the reference and call self.  */
524       gfc_conv_component_ref (se, &parent);
525       parent.u.c.sym = dt->components->ts.u.derived;
526       parent.u.c.component = c;
527       conv_parent_component_references (se, &parent);
528     }
529 }
530
531 /* Return the contents of a variable. Also handles reference/pointer
532    variables (all Fortran pointer references are implicit).  */
533
534 static void
535 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
536 {
537   gfc_ref *ref;
538   gfc_symbol *sym;
539   tree parent_decl;
540   int parent_flag;
541   bool return_value;
542   bool alternate_entry;
543   bool entry_master;
544
545   sym = expr->symtree->n.sym;
546   if (se->ss != NULL)
547     {
548       /* Check that something hasn't gone horribly wrong.  */
549       gcc_assert (se->ss != gfc_ss_terminator);
550       gcc_assert (se->ss->expr == expr);
551
552       /* A scalarized term.  We already know the descriptor.  */
553       se->expr = se->ss->data.info.descriptor;
554       se->string_length = se->ss->string_length;
555       for (ref = se->ss->data.info.ref; ref; ref = ref->next)
556         if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
557           break;
558     }
559   else
560     {
561       tree se_expr = NULL_TREE;
562
563       se->expr = gfc_get_symbol_decl (sym);
564
565       /* Deal with references to a parent results or entries by storing
566          the current_function_decl and moving to the parent_decl.  */
567       return_value = sym->attr.function && sym->result == sym;
568       alternate_entry = sym->attr.function && sym->attr.entry
569                         && sym->result == sym;
570       entry_master = sym->attr.result
571                      && sym->ns->proc_name->attr.entry_master
572                      && !gfc_return_by_reference (sym->ns->proc_name);
573       parent_decl = DECL_CONTEXT (current_function_decl);
574
575       if ((se->expr == parent_decl && return_value)
576            || (sym->ns && sym->ns->proc_name
577                && parent_decl
578                && sym->ns->proc_name->backend_decl == parent_decl
579                && (alternate_entry || entry_master)))
580         parent_flag = 1;
581       else
582         parent_flag = 0;
583
584       /* Special case for assigning the return value of a function.
585          Self recursive functions must have an explicit return value.  */
586       if (return_value && (se->expr == current_function_decl || parent_flag))
587         se_expr = gfc_get_fake_result_decl (sym, parent_flag);
588
589       /* Similarly for alternate entry points.  */
590       else if (alternate_entry 
591                && (sym->ns->proc_name->backend_decl == current_function_decl
592                    || parent_flag))
593         {
594           gfc_entry_list *el = NULL;
595
596           for (el = sym->ns->entries; el; el = el->next)
597             if (sym == el->sym)
598               {
599                 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
600                 break;
601               }
602         }
603
604       else if (entry_master
605                && (sym->ns->proc_name->backend_decl == current_function_decl
606                    || parent_flag))
607         se_expr = gfc_get_fake_result_decl (sym, parent_flag);
608
609       if (se_expr)
610         se->expr = se_expr;
611
612       /* Procedure actual arguments.  */
613       else if (sym->attr.flavor == FL_PROCEDURE
614                && se->expr != current_function_decl)
615         {
616           if (!sym->attr.dummy && !sym->attr.proc_pointer)
617             {
618               gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
619               se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
620             }
621           return;
622         }
623
624
625       /* Dereference the expression, where needed. Since characters
626          are entirely different from other types, they are treated 
627          separately.  */
628       if (sym->ts.type == BT_CHARACTER)
629         {
630           /* Dereference character pointer dummy arguments
631              or results.  */
632           if ((sym->attr.pointer || sym->attr.allocatable)
633               && (sym->attr.dummy
634                   || sym->attr.function
635                   || sym->attr.result))
636             se->expr = build_fold_indirect_ref_loc (input_location,
637                                                 se->expr);
638
639         }
640       else if (!sym->attr.value)
641         {
642           /* Dereference non-character scalar dummy arguments.  */
643           if (sym->attr.dummy && !sym->attr.dimension)
644             se->expr = build_fold_indirect_ref_loc (input_location,
645                                                 se->expr);
646
647           /* Dereference scalar hidden result.  */
648           if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
649               && (sym->attr.function || sym->attr.result)
650               && !sym->attr.dimension && !sym->attr.pointer
651               && !sym->attr.always_explicit)
652             se->expr = build_fold_indirect_ref_loc (input_location,
653                                                 se->expr);
654
655           /* Dereference non-character pointer variables. 
656              These must be dummies, results, or scalars.  */
657           if ((sym->attr.pointer || sym->attr.allocatable)
658               && (sym->attr.dummy
659                   || sym->attr.function
660                   || sym->attr.result
661                   || !sym->attr.dimension))
662             se->expr = build_fold_indirect_ref_loc (input_location,
663                                                 se->expr);
664         }
665
666       ref = expr->ref;
667     }
668
669   /* For character variables, also get the length.  */
670   if (sym->ts.type == BT_CHARACTER)
671     {
672       /* If the character length of an entry isn't set, get the length from
673          the master function instead.  */
674       if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
675         se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
676       else
677         se->string_length = sym->ts.u.cl->backend_decl;
678       gcc_assert (se->string_length);
679     }
680
681   while (ref)
682     {
683       switch (ref->type)
684         {
685         case REF_ARRAY:
686           /* Return the descriptor if that's what we want and this is an array
687              section reference.  */
688           if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
689             return;
690 /* TODO: Pointers to single elements of array sections, eg elemental subs.  */
691           /* Return the descriptor for array pointers and allocations.  */
692           if (se->want_pointer
693               && ref->next == NULL && (se->descriptor_only))
694             return;
695
696           gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
697           /* Return a pointer to an element.  */
698           break;
699
700         case REF_COMPONENT:
701           if (ref->u.c.sym->attr.extension)
702             conv_parent_component_references (se, ref);
703
704           gfc_conv_component_ref (se, ref);
705           break;
706
707         case REF_SUBSTRING:
708           gfc_conv_substring (se, ref, expr->ts.kind,
709                               expr->symtree->name, &expr->where);
710           break;
711
712         default:
713           gcc_unreachable ();
714           break;
715         }
716       ref = ref->next;
717     }
718   /* Pointer assignment, allocation or pass by reference.  Arrays are handled
719      separately.  */
720   if (se->want_pointer)
721     {
722       if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr, NULL))
723         gfc_conv_string_parameter (se);
724       else 
725         se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
726     }
727 }
728
729
730 /* Unary ops are easy... Or they would be if ! was a valid op.  */
731
732 static void
733 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
734 {
735   gfc_se operand;
736   tree type;
737
738   gcc_assert (expr->ts.type != BT_CHARACTER);
739   /* Initialize the operand.  */
740   gfc_init_se (&operand, se);
741   gfc_conv_expr_val (&operand, expr->value.op.op1);
742   gfc_add_block_to_block (&se->pre, &operand.pre);
743
744   type = gfc_typenode_for_spec (&expr->ts);
745
746   /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
747      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
748      All other unary operators have an equivalent GIMPLE unary operator.  */
749   if (code == TRUTH_NOT_EXPR)
750     se->expr = fold_build2 (EQ_EXPR, type, operand.expr,
751                             build_int_cst (type, 0));
752   else
753     se->expr = fold_build1 (code, type, operand.expr);
754
755 }
756
757 /* Expand power operator to optimal multiplications when a value is raised
758    to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
759    Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
760    Programming", 3rd Edition, 1998.  */
761
762 /* This code is mostly duplicated from expand_powi in the backend.
763    We establish the "optimal power tree" lookup table with the defined size.
764    The items in the table are the exponents used to calculate the index
765    exponents. Any integer n less than the value can get an "addition chain",
766    with the first node being one.  */
767 #define POWI_TABLE_SIZE 256
768
769 /* The table is from builtins.c.  */
770 static const unsigned char powi_table[POWI_TABLE_SIZE] =
771   {
772       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
773       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
774       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
775      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
776      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
777      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
778      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
779      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
780      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
781      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
782      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
783      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
784      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
785      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
786      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
787      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
788      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
789      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
790      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
791      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
792      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
793      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
794      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
795      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
796      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
797     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
798     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
799     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
800     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
801     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
802     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
803     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
804   };
805
806 /* If n is larger than lookup table's max index, we use the "window 
807    method".  */
808 #define POWI_WINDOW_SIZE 3
809
810 /* Recursive function to expand the power operator. The temporary 
811    values are put in tmpvar. The function returns tmpvar[1] ** n.  */
812 static tree
813 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
814 {
815   tree op0;
816   tree op1;
817   tree tmp;
818   int digit;
819
820   if (n < POWI_TABLE_SIZE)
821     {
822       if (tmpvar[n])
823         return tmpvar[n];
824
825       op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
826       op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
827     }
828   else if (n & 1)
829     {
830       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
831       op0 = gfc_conv_powi (se, n - digit, tmpvar);
832       op1 = gfc_conv_powi (se, digit, tmpvar);
833     }
834   else
835     {
836       op0 = gfc_conv_powi (se, n >> 1, tmpvar);
837       op1 = op0;
838     }
839
840   tmp = fold_build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1);
841   tmp = gfc_evaluate_now (tmp, &se->pre);
842
843   if (n < POWI_TABLE_SIZE)
844     tmpvar[n] = tmp;
845
846   return tmp;
847 }
848
849
850 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
851    return 1. Else return 0 and a call to runtime library functions
852    will have to be built.  */
853 static int
854 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
855 {
856   tree cond;
857   tree tmp;
858   tree type;
859   tree vartmp[POWI_TABLE_SIZE];
860   HOST_WIDE_INT m;
861   unsigned HOST_WIDE_INT n;
862   int sgn;
863
864   /* If exponent is too large, we won't expand it anyway, so don't bother
865      with large integer values.  */
866   if (!double_int_fits_in_shwi_p (TREE_INT_CST (rhs)))
867     return 0;
868
869   m = double_int_to_shwi (TREE_INT_CST (rhs));
870   /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
871      of the asymmetric range of the integer type.  */
872   n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
873   
874   type = TREE_TYPE (lhs);
875   sgn = tree_int_cst_sgn (rhs);
876
877   if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
878        || optimize_size) && (m > 2 || m < -1))
879     return 0;
880
881   /* rhs == 0  */
882   if (sgn == 0)
883     {
884       se->expr = gfc_build_const (type, integer_one_node);
885       return 1;
886     }
887
888   /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1.  */
889   if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
890     {
891       tmp = fold_build2 (EQ_EXPR, boolean_type_node,
892                          lhs, build_int_cst (TREE_TYPE (lhs), -1));
893       cond = fold_build2 (EQ_EXPR, boolean_type_node,
894                           lhs, build_int_cst (TREE_TYPE (lhs), 1));
895
896       /* If rhs is even,
897          result = (lhs == 1 || lhs == -1) ? 1 : 0.  */
898       if ((n & 1) == 0)
899         {
900           tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
901           se->expr = fold_build3 (COND_EXPR, type,
902                                   tmp, build_int_cst (type, 1),
903                                   build_int_cst (type, 0));
904           return 1;
905         }
906       /* If rhs is odd,
907          result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0.  */
908       tmp = fold_build3 (COND_EXPR, type, tmp, build_int_cst (type, -1),
909                          build_int_cst (type, 0));
910       se->expr = fold_build3 (COND_EXPR, type,
911                               cond, build_int_cst (type, 1), tmp);
912       return 1;
913     }
914
915   memset (vartmp, 0, sizeof (vartmp));
916   vartmp[1] = lhs;
917   if (sgn == -1)
918     {
919       tmp = gfc_build_const (type, integer_one_node);
920       vartmp[1] = fold_build2 (RDIV_EXPR, type, tmp, vartmp[1]);
921     }
922
923   se->expr = gfc_conv_powi (se, n, vartmp);
924
925   return 1;
926 }
927
928
929 /* Power op (**).  Constant integer exponent has special handling.  */
930
931 static void
932 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
933 {
934   tree gfc_int4_type_node;
935   int kind;
936   int ikind;
937   gfc_se lse;
938   gfc_se rse;
939   tree fndecl;
940
941   gfc_init_se (&lse, se);
942   gfc_conv_expr_val (&lse, expr->value.op.op1);
943   lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
944   gfc_add_block_to_block (&se->pre, &lse.pre);
945
946   gfc_init_se (&rse, se);
947   gfc_conv_expr_val (&rse, expr->value.op.op2);
948   gfc_add_block_to_block (&se->pre, &rse.pre);
949
950   if (expr->value.op.op2->ts.type == BT_INTEGER
951       && expr->value.op.op2->expr_type == EXPR_CONSTANT)
952     if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
953       return;
954
955   gfc_int4_type_node = gfc_get_int_type (4);
956
957   kind = expr->value.op.op1->ts.kind;
958   switch (expr->value.op.op2->ts.type)
959     {
960     case BT_INTEGER:
961       ikind = expr->value.op.op2->ts.kind;
962       switch (ikind)
963         {
964         case 1:
965         case 2:
966           rse.expr = convert (gfc_int4_type_node, rse.expr);
967           /* Fall through.  */
968
969         case 4:
970           ikind = 0;
971           break;
972           
973         case 8:
974           ikind = 1;
975           break;
976
977         case 16:
978           ikind = 2;
979           break;
980
981         default:
982           gcc_unreachable ();
983         }
984       switch (kind)
985         {
986         case 1:
987         case 2:
988           if (expr->value.op.op1->ts.type == BT_INTEGER)
989             lse.expr = convert (gfc_int4_type_node, lse.expr);
990           else
991             gcc_unreachable ();
992           /* Fall through.  */
993
994         case 4:
995           kind = 0;
996           break;
997           
998         case 8:
999           kind = 1;
1000           break;
1001
1002         case 10:
1003           kind = 2;
1004           break;
1005
1006         case 16:
1007           kind = 3;
1008           break;
1009
1010         default:
1011           gcc_unreachable ();
1012         }
1013       
1014       switch (expr->value.op.op1->ts.type)
1015         {
1016         case BT_INTEGER:
1017           if (kind == 3) /* Case 16 was not handled properly above.  */
1018             kind = 2;
1019           fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
1020           break;
1021
1022         case BT_REAL:
1023           /* Use builtins for real ** int4.  */
1024           if (ikind == 0)
1025             {
1026               switch (kind)
1027                 {
1028                 case 0:
1029                   fndecl = built_in_decls[BUILT_IN_POWIF];
1030                   break;
1031                 
1032                 case 1:
1033                   fndecl = built_in_decls[BUILT_IN_POWI];
1034                   break;
1035
1036                 case 2:
1037                 case 3:
1038                   fndecl = built_in_decls[BUILT_IN_POWIL];
1039                   break;
1040
1041                 default:
1042                   gcc_unreachable ();
1043                 }
1044             }
1045           else
1046             fndecl = gfor_fndecl_math_powi[kind][ikind].real;
1047           break;
1048
1049         case BT_COMPLEX:
1050           fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
1051           break;
1052
1053         default:
1054           gcc_unreachable ();
1055         }
1056       break;
1057
1058     case BT_REAL:
1059       switch (kind)
1060         {
1061         case 4:
1062           fndecl = built_in_decls[BUILT_IN_POWF];
1063           break;
1064         case 8:
1065           fndecl = built_in_decls[BUILT_IN_POW];
1066           break;
1067         case 10:
1068         case 16:
1069           fndecl = built_in_decls[BUILT_IN_POWL];
1070           break;
1071         default:
1072           gcc_unreachable ();
1073         }
1074       break;
1075
1076     case BT_COMPLEX:
1077       switch (kind)
1078         {
1079         case 4:
1080           fndecl = built_in_decls[BUILT_IN_CPOWF];
1081           break;
1082         case 8:
1083           fndecl = built_in_decls[BUILT_IN_CPOW];
1084           break;
1085         case 10:
1086         case 16:
1087           fndecl = built_in_decls[BUILT_IN_CPOWL];
1088           break;
1089         default:
1090           gcc_unreachable ();
1091         }
1092       break;
1093
1094     default:
1095       gcc_unreachable ();
1096       break;
1097     }
1098
1099   se->expr = build_call_expr_loc (input_location,
1100                               fndecl, 2, lse.expr, rse.expr);
1101 }
1102
1103
1104 /* Generate code to allocate a string temporary.  */
1105
1106 tree
1107 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
1108 {
1109   tree var;
1110   tree tmp;
1111
1112   gcc_assert (types_compatible_p (TREE_TYPE (len), gfc_charlen_type_node));
1113
1114   if (gfc_can_put_var_on_stack (len))
1115     {
1116       /* Create a temporary variable to hold the result.  */
1117       tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
1118                          build_int_cst (gfc_charlen_type_node, 1));
1119       tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
1120
1121       if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
1122         tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
1123       else
1124         tmp = build_array_type (TREE_TYPE (type), tmp);
1125
1126       var = gfc_create_var (tmp, "str");
1127       var = gfc_build_addr_expr (type, var);
1128     }
1129   else
1130     {
1131       /* Allocate a temporary to hold the result.  */
1132       var = gfc_create_var (type, "pstr");
1133       tmp = gfc_call_malloc (&se->pre, type,
1134                              fold_build2 (MULT_EXPR, TREE_TYPE (len), len,
1135                                           fold_convert (TREE_TYPE (len),
1136                                                         TYPE_SIZE (type))));
1137       gfc_add_modify (&se->pre, var, tmp);
1138
1139       /* Free the temporary afterwards.  */
1140       tmp = gfc_call_free (convert (pvoid_type_node, var));
1141       gfc_add_expr_to_block (&se->post, tmp);
1142     }
1143
1144   return var;
1145 }
1146
1147
1148 /* Handle a string concatenation operation.  A temporary will be allocated to
1149    hold the result.  */
1150
1151 static void
1152 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
1153 {
1154   gfc_se lse, rse;
1155   tree len, type, var, tmp, fndecl;
1156
1157   gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
1158               && expr->value.op.op2->ts.type == BT_CHARACTER);
1159   gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
1160
1161   gfc_init_se (&lse, se);
1162   gfc_conv_expr (&lse, expr->value.op.op1);
1163   gfc_conv_string_parameter (&lse);
1164   gfc_init_se (&rse, se);
1165   gfc_conv_expr (&rse, expr->value.op.op2);
1166   gfc_conv_string_parameter (&rse);
1167
1168   gfc_add_block_to_block (&se->pre, &lse.pre);
1169   gfc_add_block_to_block (&se->pre, &rse.pre);
1170
1171   type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
1172   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1173   if (len == NULL_TREE)
1174     {
1175       len = fold_build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
1176                          lse.string_length, rse.string_length);
1177     }
1178
1179   type = build_pointer_type (type);
1180
1181   var = gfc_conv_string_tmp (se, type, len);
1182
1183   /* Do the actual concatenation.  */
1184   if (expr->ts.kind == 1)
1185     fndecl = gfor_fndecl_concat_string;
1186   else if (expr->ts.kind == 4)
1187     fndecl = gfor_fndecl_concat_string_char4;
1188   else
1189     gcc_unreachable ();
1190
1191   tmp = build_call_expr_loc (input_location,
1192                          fndecl, 6, len, var, lse.string_length, lse.expr,
1193                          rse.string_length, rse.expr);
1194   gfc_add_expr_to_block (&se->pre, tmp);
1195
1196   /* Add the cleanup for the operands.  */
1197   gfc_add_block_to_block (&se->pre, &rse.post);
1198   gfc_add_block_to_block (&se->pre, &lse.post);
1199
1200   se->expr = var;
1201   se->string_length = len;
1202 }
1203
1204 /* Translates an op expression. Common (binary) cases are handled by this
1205    function, others are passed on. Recursion is used in either case.
1206    We use the fact that (op1.ts == op2.ts) (except for the power
1207    operator **).
1208    Operators need no special handling for scalarized expressions as long as
1209    they call gfc_conv_simple_val to get their operands.
1210    Character strings get special handling.  */
1211
1212 static void
1213 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
1214 {
1215   enum tree_code code;
1216   gfc_se lse;
1217   gfc_se rse;
1218   tree tmp, type;
1219   int lop;
1220   int checkstring;
1221
1222   checkstring = 0;
1223   lop = 0;
1224   switch (expr->value.op.op)
1225     {
1226     case INTRINSIC_PARENTHESES:
1227       if (expr->ts.type == BT_REAL
1228           || expr->ts.type == BT_COMPLEX)
1229         {
1230           gfc_conv_unary_op (PAREN_EXPR, se, expr);
1231           gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
1232           return;
1233         }
1234
1235       /* Fallthrough.  */
1236     case INTRINSIC_UPLUS:
1237       gfc_conv_expr (se, expr->value.op.op1);
1238       return;
1239
1240     case INTRINSIC_UMINUS:
1241       gfc_conv_unary_op (NEGATE_EXPR, se, expr);
1242       return;
1243
1244     case INTRINSIC_NOT:
1245       gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
1246       return;
1247
1248     case INTRINSIC_PLUS:
1249       code = PLUS_EXPR;
1250       break;
1251
1252     case INTRINSIC_MINUS:
1253       code = MINUS_EXPR;
1254       break;
1255
1256     case INTRINSIC_TIMES:
1257       code = MULT_EXPR;
1258       break;
1259
1260     case INTRINSIC_DIVIDE:
1261       /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1262          an integer, we must round towards zero, so we use a
1263          TRUNC_DIV_EXPR.  */
1264       if (expr->ts.type == BT_INTEGER)
1265         code = TRUNC_DIV_EXPR;
1266       else
1267         code = RDIV_EXPR;
1268       break;
1269
1270     case INTRINSIC_POWER:
1271       gfc_conv_power_op (se, expr);
1272       return;
1273
1274     case INTRINSIC_CONCAT:
1275       gfc_conv_concat_op (se, expr);
1276       return;
1277
1278     case INTRINSIC_AND:
1279       code = TRUTH_ANDIF_EXPR;
1280       lop = 1;
1281       break;
1282
1283     case INTRINSIC_OR:
1284       code = TRUTH_ORIF_EXPR;
1285       lop = 1;
1286       break;
1287
1288       /* EQV and NEQV only work on logicals, but since we represent them
1289          as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
1290     case INTRINSIC_EQ:
1291     case INTRINSIC_EQ_OS:
1292     case INTRINSIC_EQV:
1293       code = EQ_EXPR;
1294       checkstring = 1;
1295       lop = 1;
1296       break;
1297
1298     case INTRINSIC_NE:
1299     case INTRINSIC_NE_OS:
1300     case INTRINSIC_NEQV:
1301       code = NE_EXPR;
1302       checkstring = 1;
1303       lop = 1;
1304       break;
1305
1306     case INTRINSIC_GT:
1307     case INTRINSIC_GT_OS:
1308       code = GT_EXPR;
1309       checkstring = 1;
1310       lop = 1;
1311       break;
1312
1313     case INTRINSIC_GE:
1314     case INTRINSIC_GE_OS:
1315       code = GE_EXPR;
1316       checkstring = 1;
1317       lop = 1;
1318       break;
1319
1320     case INTRINSIC_LT:
1321     case INTRINSIC_LT_OS:
1322       code = LT_EXPR;
1323       checkstring = 1;
1324       lop = 1;
1325       break;
1326
1327     case INTRINSIC_LE:
1328     case INTRINSIC_LE_OS:
1329       code = LE_EXPR;
1330       checkstring = 1;
1331       lop = 1;
1332       break;
1333
1334     case INTRINSIC_USER:
1335     case INTRINSIC_ASSIGN:
1336       /* These should be converted into function calls by the frontend.  */
1337       gcc_unreachable ();
1338
1339     default:
1340       fatal_error ("Unknown intrinsic op");
1341       return;
1342     }
1343
1344   /* The only exception to this is **, which is handled separately anyway.  */
1345   gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
1346
1347   if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
1348     checkstring = 0;
1349
1350   /* lhs */
1351   gfc_init_se (&lse, se);
1352   gfc_conv_expr (&lse, expr->value.op.op1);
1353   gfc_add_block_to_block (&se->pre, &lse.pre);
1354
1355   /* rhs */
1356   gfc_init_se (&rse, se);
1357   gfc_conv_expr (&rse, expr->value.op.op2);
1358   gfc_add_block_to_block (&se->pre, &rse.pre);
1359
1360   if (checkstring)
1361     {
1362       gfc_conv_string_parameter (&lse);
1363       gfc_conv_string_parameter (&rse);
1364
1365       lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
1366                                            rse.string_length, rse.expr,
1367                                            expr->value.op.op1->ts.kind);
1368       rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
1369       gfc_add_block_to_block (&lse.post, &rse.post);
1370     }
1371
1372   type = gfc_typenode_for_spec (&expr->ts);
1373
1374   if (lop)
1375     {
1376       /* The result of logical ops is always boolean_type_node.  */
1377       tmp = fold_build2 (code, boolean_type_node, lse.expr, rse.expr);
1378       se->expr = convert (type, tmp);
1379     }
1380   else
1381     se->expr = fold_build2 (code, type, lse.expr, rse.expr);
1382
1383   /* Add the post blocks.  */
1384   gfc_add_block_to_block (&se->post, &rse.post);
1385   gfc_add_block_to_block (&se->post, &lse.post);
1386 }
1387
1388 /* If a string's length is one, we convert it to a single character.  */
1389
1390 static tree
1391 string_to_single_character (tree len, tree str, int kind)
1392 {
1393   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
1394
1395   if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
1396       && TREE_INT_CST_HIGH (len) == 0)
1397     {
1398       str = fold_convert (gfc_get_pchar_type (kind), str);
1399       return build_fold_indirect_ref_loc (input_location,
1400                                       str);
1401     }
1402
1403   return NULL_TREE;
1404 }
1405
1406
1407 void
1408 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
1409 {
1410
1411   if (sym->backend_decl)
1412     {
1413       /* This becomes the nominal_type in
1414          function.c:assign_parm_find_data_types.  */
1415       TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
1416       /* This becomes the passed_type in
1417          function.c:assign_parm_find_data_types.  C promotes char to
1418          integer for argument passing.  */
1419       DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
1420
1421       DECL_BY_REFERENCE (sym->backend_decl) = 0;
1422     }
1423
1424   if (expr != NULL)
1425     {
1426       /* If we have a constant character expression, make it into an
1427          integer.  */
1428       if ((*expr)->expr_type == EXPR_CONSTANT)
1429         {
1430           gfc_typespec ts;
1431           gfc_clear_ts (&ts);
1432
1433           *expr = gfc_int_expr ((int)(*expr)->value.character.string[0]);
1434           if ((*expr)->ts.kind != gfc_c_int_kind)
1435             {
1436               /* The expr needs to be compatible with a C int.  If the 
1437                  conversion fails, then the 2 causes an ICE.  */
1438               ts.type = BT_INTEGER;
1439               ts.kind = gfc_c_int_kind;
1440               gfc_convert_type (*expr, &ts, 2);
1441             }
1442         }
1443       else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
1444         {
1445           if ((*expr)->ref == NULL)
1446             {
1447               se->expr = string_to_single_character
1448                 (build_int_cst (integer_type_node, 1),
1449                  gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
1450                                       gfc_get_symbol_decl
1451                                       ((*expr)->symtree->n.sym)),
1452                  (*expr)->ts.kind);
1453             }
1454           else
1455             {
1456               gfc_conv_variable (se, *expr);
1457               se->expr = string_to_single_character
1458                 (build_int_cst (integer_type_node, 1),
1459                  gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
1460                                       se->expr),
1461                  (*expr)->ts.kind);
1462             }
1463         }
1464     }
1465 }
1466
1467
1468 /* Compare two strings. If they are all single characters, the result is the
1469    subtraction of them. Otherwise, we build a library call.  */
1470
1471 tree
1472 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind)
1473 {
1474   tree sc1;
1475   tree sc2;
1476   tree tmp;
1477
1478   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
1479   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
1480
1481   sc1 = string_to_single_character (len1, str1, kind);
1482   sc2 = string_to_single_character (len2, str2, kind);
1483
1484   if (sc1 != NULL_TREE && sc2 != NULL_TREE)
1485     {
1486       /* Deal with single character specially.  */
1487       sc1 = fold_convert (integer_type_node, sc1);
1488       sc2 = fold_convert (integer_type_node, sc2);
1489       tmp = fold_build2 (MINUS_EXPR, integer_type_node, sc1, sc2);
1490     }
1491   else
1492     {
1493       /* Build a call for the comparison.  */
1494       tree fndecl;
1495
1496       if (kind == 1)
1497         fndecl = gfor_fndecl_compare_string;
1498       else if (kind == 4)
1499         fndecl = gfor_fndecl_compare_string_char4;
1500       else
1501         gcc_unreachable ();
1502
1503       tmp = build_call_expr_loc (input_location,
1504                              fndecl, 4, len1, str1, len2, str2);
1505     }
1506
1507   return tmp;
1508 }
1509
1510
1511 /* Return the backend_decl for a procedure pointer component.  */
1512
1513 static tree
1514 get_proc_ptr_comp (gfc_expr *e)
1515 {
1516   gfc_se comp_se;
1517   gfc_expr *e2;
1518   gfc_init_se (&comp_se, NULL);
1519   e2 = gfc_copy_expr (e);
1520   e2->expr_type = EXPR_VARIABLE;
1521   gfc_conv_expr (&comp_se, e2);
1522   gfc_free_expr (e2);
1523   return build_fold_addr_expr_loc (input_location, comp_se.expr);
1524 }
1525
1526
1527 /* Select a class typebound procedure at runtime.  */
1528 static void
1529 select_class_proc (gfc_se *se, gfc_class_esym_list *elist,
1530                    tree declared, gfc_expr *expr)
1531 {
1532   tree end_label;
1533   tree label;
1534   tree tmp;
1535   tree vindex;
1536   stmtblock_t body;
1537   gfc_class_esym_list *next_elist, *tmp_elist;
1538   gfc_se tmpse;
1539
1540   /* Convert the vindex expression.  */
1541   gfc_init_se (&tmpse, NULL);
1542   gfc_conv_expr (&tmpse, elist->vindex);
1543   gfc_add_block_to_block (&se->pre, &tmpse.pre);
1544   vindex = gfc_evaluate_now (tmpse.expr, &se->pre);
1545   gfc_add_block_to_block (&se->post, &tmpse.post);
1546
1547   /* Fix the function type to be that of the declared type method.  */
1548   declared = gfc_create_var (TREE_TYPE (declared), "method");
1549
1550   end_label = gfc_build_label_decl (NULL_TREE);
1551
1552   gfc_init_block (&body);
1553
1554   /* Go through the list of extensions.  */
1555   for (; elist; elist = next_elist)
1556     {
1557       /* This case has already been added.  */
1558       if (elist->derived == NULL)
1559         goto free_elist;
1560
1561       /* Run through the chain picking up all the cases that call the
1562          same procedure.  */
1563       tmp_elist = elist;
1564       for (; elist; elist = elist->next)
1565         {
1566           tree cval;
1567
1568           if (elist->esym != tmp_elist->esym)
1569             continue;
1570
1571           cval = build_int_cst (TREE_TYPE (vindex),
1572                                 elist->derived->vindex);
1573           /* Build a label for the vindex value.  */
1574           label = gfc_build_label_decl (NULL_TREE);
1575           tmp = fold_build3 (CASE_LABEL_EXPR, void_type_node,
1576                              cval, NULL_TREE, label);
1577           gfc_add_expr_to_block (&body, tmp);
1578
1579           /* Null the reference the derived type so that this case is
1580              not used again.  */
1581           elist->derived = NULL;
1582         }
1583
1584       elist = tmp_elist;
1585
1586       /* Get a pointer to the procedure,  */
1587       tmp = gfc_get_symbol_decl (elist->esym);
1588       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1589         {
1590           gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1591           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1592         }
1593
1594       /* Assign the pointer to the appropriate procedure.  */
1595       gfc_add_modify (&body, declared,
1596                       fold_convert (TREE_TYPE (declared), tmp));
1597
1598       /* Break to the end of the construct.  */
1599       tmp = build1_v (GOTO_EXPR, end_label);
1600       gfc_add_expr_to_block (&body, tmp);
1601
1602       /* Free the elists as we go; freeing them in gfc_free_expr causes
1603          segfaults because it occurs too early and too often.  */
1604     free_elist:
1605       next_elist = elist->next;
1606       if (elist->vindex)
1607         gfc_free_expr (elist->vindex);
1608       gfc_free (elist);
1609       elist = NULL;
1610     }
1611
1612   /* Default is an error.  */
1613   label = gfc_build_label_decl (NULL_TREE);
1614   tmp = fold_build3 (CASE_LABEL_EXPR, void_type_node,
1615                      NULL_TREE, NULL_TREE, label);
1616   gfc_add_expr_to_block (&body, tmp);
1617   tmp = gfc_trans_runtime_error (true, &expr->where,
1618                 "internal error: bad vindex in dynamic dispatch");
1619   gfc_add_expr_to_block (&body, tmp);
1620
1621   /* Write the switch expression.  */
1622   tmp = gfc_finish_block (&body);
1623   tmp = build3_v (SWITCH_EXPR, vindex, tmp, NULL_TREE);
1624   gfc_add_expr_to_block (&se->pre, tmp);
1625
1626   tmp = build1_v (LABEL_EXPR, end_label);
1627   gfc_add_expr_to_block (&se->pre, tmp);
1628
1629   se->expr = declared;
1630   return;
1631 }
1632
1633
1634 static void
1635 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
1636 {
1637   tree tmp;
1638
1639   if (expr && expr->symtree
1640         && expr->value.function.class_esym)
1641     {
1642       if (!sym->backend_decl)
1643         sym->backend_decl = gfc_get_extern_function_decl (sym);
1644
1645       tmp = sym->backend_decl;
1646
1647       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1648         {
1649           gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1650           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1651         }
1652
1653       select_class_proc (se, expr->value.function.class_esym,
1654                          tmp, expr);
1655       return;
1656     }
1657
1658   if (gfc_is_proc_ptr_comp (expr, NULL))
1659     tmp = get_proc_ptr_comp (expr);
1660   else if (sym->attr.dummy)
1661     {
1662       tmp = gfc_get_symbol_decl (sym);
1663       if (sym->attr.proc_pointer)
1664         tmp = build_fold_indirect_ref_loc (input_location,
1665                                        tmp);
1666       gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1667               && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
1668     }
1669   else
1670     {
1671       if (!sym->backend_decl)
1672         sym->backend_decl = gfc_get_extern_function_decl (sym);
1673
1674       tmp = sym->backend_decl;
1675
1676       if (sym->attr.cray_pointee)
1677         {
1678           /* TODO - make the cray pointee a pointer to a procedure,
1679              assign the pointer to it and use it for the call.  This
1680              will do for now!  */
1681           tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
1682                          gfc_get_symbol_decl (sym->cp_pointer));
1683           tmp = gfc_evaluate_now (tmp, &se->pre);
1684         }
1685
1686       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1687         {
1688           gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1689           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1690         }
1691     }
1692   se->expr = tmp;
1693 }
1694
1695
1696 /* Initialize MAPPING.  */
1697
1698 void
1699 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
1700 {
1701   mapping->syms = NULL;
1702   mapping->charlens = NULL;
1703 }
1704
1705
1706 /* Free all memory held by MAPPING (but not MAPPING itself).  */
1707
1708 void
1709 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
1710 {
1711   gfc_interface_sym_mapping *sym;
1712   gfc_interface_sym_mapping *nextsym;
1713   gfc_charlen *cl;
1714   gfc_charlen *nextcl;
1715
1716   for (sym = mapping->syms; sym; sym = nextsym)
1717     {
1718       nextsym = sym->next;
1719       sym->new_sym->n.sym->formal = NULL;
1720       gfc_free_symbol (sym->new_sym->n.sym);
1721       gfc_free_expr (sym->expr);
1722       gfc_free (sym->new_sym);
1723       gfc_free (sym);
1724     }
1725   for (cl = mapping->charlens; cl; cl = nextcl)
1726     {
1727       nextcl = cl->next;
1728       gfc_free_expr (cl->length);
1729       gfc_free (cl);
1730     }
1731 }
1732
1733
1734 /* Return a copy of gfc_charlen CL.  Add the returned structure to
1735    MAPPING so that it will be freed by gfc_free_interface_mapping.  */
1736
1737 static gfc_charlen *
1738 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
1739                                    gfc_charlen * cl)
1740 {
1741   gfc_charlen *new_charlen;
1742
1743   new_charlen = gfc_get_charlen ();
1744   new_charlen->next = mapping->charlens;
1745   new_charlen->length = gfc_copy_expr (cl->length);
1746
1747   mapping->charlens = new_charlen;
1748   return new_charlen;
1749 }
1750
1751
1752 /* A subroutine of gfc_add_interface_mapping.  Return a descriptorless
1753    array variable that can be used as the actual argument for dummy
1754    argument SYM.  Add any initialization code to BLOCK.  PACKED is as
1755    for gfc_get_nodesc_array_type and DATA points to the first element
1756    in the passed array.  */
1757
1758 static tree
1759 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
1760                                  gfc_packed packed, tree data)
1761 {
1762   tree type;
1763   tree var;
1764
1765   type = gfc_typenode_for_spec (&sym->ts);
1766   type = gfc_get_nodesc_array_type (type, sym->as, packed,
1767                                     !sym->attr.target && !sym->attr.pointer
1768                                     && !sym->attr.proc_pointer);
1769
1770   var = gfc_create_var (type, "ifm");
1771   gfc_add_modify (block, var, fold_convert (type, data));
1772
1773   return var;
1774 }
1775
1776
1777 /* A subroutine of gfc_add_interface_mapping.  Set the stride, upper bounds
1778    and offset of descriptorless array type TYPE given that it has the same
1779    size as DESC.  Add any set-up code to BLOCK.  */
1780
1781 static void
1782 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
1783 {
1784   int n;
1785   tree dim;
1786   tree offset;
1787   tree tmp;
1788
1789   offset = gfc_index_zero_node;
1790   for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
1791     {
1792       dim = gfc_rank_cst[n];
1793       GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
1794       if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
1795         {
1796           GFC_TYPE_ARRAY_LBOUND (type, n)
1797                 = gfc_conv_descriptor_lbound_get (desc, dim);
1798           GFC_TYPE_ARRAY_UBOUND (type, n)
1799                 = gfc_conv_descriptor_ubound_get (desc, dim);
1800         }
1801       else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
1802         {
1803           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1804                              gfc_conv_descriptor_ubound_get (desc, dim),
1805                              gfc_conv_descriptor_lbound_get (desc, dim));
1806           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1807                              GFC_TYPE_ARRAY_LBOUND (type, n),
1808                              tmp);
1809           tmp = gfc_evaluate_now (tmp, block);
1810           GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
1811         }
1812       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
1813                          GFC_TYPE_ARRAY_LBOUND (type, n),
1814                          GFC_TYPE_ARRAY_STRIDE (type, n));
1815       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
1816     }
1817   offset = gfc_evaluate_now (offset, block);
1818   GFC_TYPE_ARRAY_OFFSET (type) = offset;
1819 }
1820
1821
1822 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
1823    in SE.  The caller may still use se->expr and se->string_length after
1824    calling this function.  */
1825
1826 void
1827 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
1828                            gfc_symbol * sym, gfc_se * se,
1829                            gfc_expr *expr)
1830 {
1831   gfc_interface_sym_mapping *sm;
1832   tree desc;
1833   tree tmp;
1834   tree value;
1835   gfc_symbol *new_sym;
1836   gfc_symtree *root;
1837   gfc_symtree *new_symtree;
1838
1839   /* Create a new symbol to represent the actual argument.  */
1840   new_sym = gfc_new_symbol (sym->name, NULL);
1841   new_sym->ts = sym->ts;
1842   new_sym->as = gfc_copy_array_spec (sym->as);
1843   new_sym->attr.referenced = 1;
1844   new_sym->attr.dimension = sym->attr.dimension;
1845   new_sym->attr.pointer = sym->attr.pointer;
1846   new_sym->attr.allocatable = sym->attr.allocatable;
1847   new_sym->attr.flavor = sym->attr.flavor;
1848   new_sym->attr.function = sym->attr.function;
1849
1850   /* Ensure that the interface is available and that
1851      descriptors are passed for array actual arguments.  */
1852   if (sym->attr.flavor == FL_PROCEDURE)
1853     {
1854       new_sym->formal = expr->symtree->n.sym->formal;
1855       new_sym->attr.always_explicit
1856             = expr->symtree->n.sym->attr.always_explicit;
1857     }
1858
1859   /* Create a fake symtree for it.  */
1860   root = NULL;
1861   new_symtree = gfc_new_symtree (&root, sym->name);
1862   new_symtree->n.sym = new_sym;
1863   gcc_assert (new_symtree == root);
1864
1865   /* Create a dummy->actual mapping.  */
1866   sm = XCNEW (gfc_interface_sym_mapping);
1867   sm->next = mapping->syms;
1868   sm->old = sym;
1869   sm->new_sym = new_symtree;
1870   sm->expr = gfc_copy_expr (expr);
1871   mapping->syms = sm;
1872
1873   /* Stabilize the argument's value.  */
1874   if (!sym->attr.function && se)
1875     se->expr = gfc_evaluate_now (se->expr, &se->pre);
1876
1877   if (sym->ts.type == BT_CHARACTER)
1878     {
1879       /* Create a copy of the dummy argument's length.  */
1880       new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
1881       sm->expr->ts.u.cl = new_sym->ts.u.cl;
1882
1883       /* If the length is specified as "*", record the length that
1884          the caller is passing.  We should use the callee's length
1885          in all other cases.  */
1886       if (!new_sym->ts.u.cl->length && se)
1887         {
1888           se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
1889           new_sym->ts.u.cl->backend_decl = se->string_length;
1890         }
1891     }
1892
1893   if (!se)
1894     return;
1895
1896   /* Use the passed value as-is if the argument is a function.  */
1897   if (sym->attr.flavor == FL_PROCEDURE)
1898     value = se->expr;
1899
1900   /* If the argument is either a string or a pointer to a string,
1901      convert it to a boundless character type.  */
1902   else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
1903     {
1904       tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
1905       tmp = build_pointer_type (tmp);
1906       if (sym->attr.pointer)
1907         value = build_fold_indirect_ref_loc (input_location,
1908                                          se->expr);
1909       else
1910         value = se->expr;
1911       value = fold_convert (tmp, value);
1912     }
1913
1914   /* If the argument is a scalar, a pointer to an array or an allocatable,
1915      dereference it.  */
1916   else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
1917     value = build_fold_indirect_ref_loc (input_location,
1918                                      se->expr);
1919   
1920   /* For character(*), use the actual argument's descriptor.  */  
1921   else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
1922     value = build_fold_indirect_ref_loc (input_location,
1923                                      se->expr);
1924
1925   /* If the argument is an array descriptor, use it to determine
1926      information about the actual argument's shape.  */
1927   else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
1928            && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
1929     {
1930       /* Get the actual argument's descriptor.  */
1931       desc = build_fold_indirect_ref_loc (input_location,
1932                                       se->expr);
1933
1934       /* Create the replacement variable.  */
1935       tmp = gfc_conv_descriptor_data_get (desc);
1936       value = gfc_get_interface_mapping_array (&se->pre, sym,
1937                                                PACKED_NO, tmp);
1938
1939       /* Use DESC to work out the upper bounds, strides and offset.  */
1940       gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
1941     }
1942   else
1943     /* Otherwise we have a packed array.  */
1944     value = gfc_get_interface_mapping_array (&se->pre, sym,
1945                                              PACKED_FULL, se->expr);
1946
1947   new_sym->backend_decl = value;
1948 }
1949
1950
1951 /* Called once all dummy argument mappings have been added to MAPPING,
1952    but before the mapping is used to evaluate expressions.  Pre-evaluate
1953    the length of each argument, adding any initialization code to PRE and
1954    any finalization code to POST.  */
1955
1956 void
1957 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
1958                               stmtblock_t * pre, stmtblock_t * post)
1959 {
1960   gfc_interface_sym_mapping *sym;
1961   gfc_expr *expr;
1962   gfc_se se;
1963
1964   for (sym = mapping->syms; sym; sym = sym->next)
1965     if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
1966         && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
1967       {
1968         expr = sym->new_sym->n.sym->ts.u.cl->length;
1969         gfc_apply_interface_mapping_to_expr (mapping, expr);
1970         gfc_init_se (&se, NULL);
1971         gfc_conv_expr (&se, expr);
1972         se.expr = fold_convert (gfc_charlen_type_node, se.expr);
1973         se.expr = gfc_evaluate_now (se.expr, &se.pre);
1974         gfc_add_block_to_block (pre, &se.pre);
1975         gfc_add_block_to_block (post, &se.post);
1976
1977         sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
1978       }
1979 }
1980
1981
1982 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1983    constructor C.  */
1984
1985 static void
1986 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
1987                                      gfc_constructor * c)
1988 {
1989   for (; c; c = c->next)
1990     {
1991       gfc_apply_interface_mapping_to_expr (mapping, c->expr);
1992       if (c->iterator)
1993         {
1994           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
1995           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
1996           gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
1997         }
1998     }
1999 }
2000
2001
2002 /* Like gfc_apply_interface_mapping_to_expr, but applied to
2003    reference REF.  */
2004
2005 static void
2006 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
2007                                     gfc_ref * ref)
2008 {
2009   int n;
2010
2011   for (; ref; ref = ref->next)
2012     switch (ref->type)
2013       {
2014       case REF_ARRAY:
2015         for (n = 0; n < ref->u.ar.dimen; n++)
2016           {
2017             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
2018             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
2019             gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
2020           }
2021         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
2022         break;
2023
2024       case REF_COMPONENT:
2025         break;
2026
2027       case REF_SUBSTRING:
2028         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
2029         gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
2030         break;
2031       }
2032 }
2033
2034
2035 /* Convert intrinsic function calls into result expressions.  */
2036
2037 static bool
2038 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
2039 {
2040   gfc_symbol *sym;
2041   gfc_expr *new_expr;
2042   gfc_expr *arg1;
2043   gfc_expr *arg2;
2044   int d, dup;
2045
2046   arg1 = expr->value.function.actual->expr;
2047   if (expr->value.function.actual->next)
2048     arg2 = expr->value.function.actual->next->expr;
2049   else
2050     arg2 = NULL;
2051
2052   sym = arg1->symtree->n.sym;
2053
2054   if (sym->attr.dummy)
2055     return false;
2056
2057   new_expr = NULL;
2058
2059   switch (expr->value.function.isym->id)
2060     {
2061     case GFC_ISYM_LEN:
2062       /* TODO figure out why this condition is necessary.  */
2063       if (sym->attr.function
2064           && (arg1->ts.u.cl->length == NULL
2065               || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
2066                   && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
2067         return false;
2068
2069       new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
2070       break;
2071
2072     case GFC_ISYM_SIZE:
2073       if (!sym->as)
2074         return false;
2075
2076       if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2077         {
2078           dup = mpz_get_si (arg2->value.integer);
2079           d = dup - 1;
2080         }
2081       else
2082         {
2083           dup = sym->as->rank;
2084           d = 0;
2085         }
2086
2087       for (; d < dup; d++)
2088         {
2089           gfc_expr *tmp;
2090
2091           if (!sym->as->upper[d] || !sym->as->lower[d])
2092             {
2093               gfc_free_expr (new_expr);
2094               return false;
2095             }
2096
2097           tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]), gfc_int_expr (1));
2098           tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
2099           if (new_expr)
2100             new_expr = gfc_multiply (new_expr, tmp);
2101           else
2102             new_expr = tmp;
2103         }
2104       break;
2105
2106     case GFC_ISYM_LBOUND:
2107     case GFC_ISYM_UBOUND:
2108         /* TODO These implementations of lbound and ubound do not limit if
2109            the size < 0, according to F95's 13.14.53 and 13.14.113.  */
2110
2111       if (!sym->as)
2112         return false;
2113
2114       if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2115         d = mpz_get_si (arg2->value.integer) - 1;
2116       else
2117         /* TODO: If the need arises, this could produce an array of
2118            ubound/lbounds.  */
2119         gcc_unreachable ();
2120
2121       if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
2122         {
2123           if (sym->as->lower[d])
2124             new_expr = gfc_copy_expr (sym->as->lower[d]);
2125         }
2126       else
2127         {
2128           if (sym->as->upper[d])
2129             new_expr = gfc_copy_expr (sym->as->upper[d]);
2130         }
2131       break;
2132
2133     default:
2134       break;
2135     }
2136
2137   gfc_apply_interface_mapping_to_expr (mapping, new_expr);
2138   if (!new_expr)
2139     return false;
2140
2141   gfc_replace_expr (expr, new_expr);
2142   return true;
2143 }
2144
2145
2146 static void
2147 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
2148                               gfc_interface_mapping * mapping)
2149 {
2150   gfc_formal_arglist *f;
2151   gfc_actual_arglist *actual;
2152
2153   actual = expr->value.function.actual;
2154   f = map_expr->symtree->n.sym->formal;
2155
2156   for (; f && actual; f = f->next, actual = actual->next)
2157     {
2158       if (!actual->expr)
2159         continue;
2160
2161       gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
2162     }
2163
2164   if (map_expr->symtree->n.sym->attr.dimension)
2165     {
2166       int d;
2167       gfc_array_spec *as;
2168
2169       as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
2170
2171       for (d = 0; d < as->rank; d++)
2172         {
2173           gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
2174           gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
2175         }
2176
2177       expr->value.function.esym->as = as;
2178     }
2179
2180   if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
2181     {
2182       expr->value.function.esym->ts.u.cl->length
2183         = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
2184
2185       gfc_apply_interface_mapping_to_expr (mapping,
2186                         expr->value.function.esym->ts.u.cl->length);
2187     }
2188 }
2189
2190
2191 /* EXPR is a copy of an expression that appeared in the interface
2192    associated with MAPPING.  Walk it recursively looking for references to
2193    dummy arguments that MAPPING maps to actual arguments.  Replace each such
2194    reference with a reference to the associated actual argument.  */
2195
2196 static void
2197 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
2198                                      gfc_expr * expr)
2199 {
2200   gfc_interface_sym_mapping *sym;
2201   gfc_actual_arglist *actual;
2202
2203   if (!expr)
2204     return;
2205
2206   /* Copying an expression does not copy its length, so do that here.  */
2207   if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
2208     {
2209       expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
2210       gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
2211     }
2212
2213   /* Apply the mapping to any references.  */
2214   gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
2215
2216   /* ...and to the expression's symbol, if it has one.  */
2217   /* TODO Find out why the condition on expr->symtree had to be moved into
2218      the loop rather than being outside it, as originally.  */
2219   for (sym = mapping->syms; sym; sym = sym->next)
2220     if (expr->symtree && sym->old == expr->symtree->n.sym)
2221       {
2222         if (sym->new_sym->n.sym->backend_decl)
2223           expr->symtree = sym->new_sym;
2224         else if (sym->expr)
2225           gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
2226       }
2227
2228       /* ...and to subexpressions in expr->value.  */
2229   switch (expr->expr_type)
2230     {
2231     case EXPR_VARIABLE:
2232     case EXPR_CONSTANT:
2233     case EXPR_NULL:
2234     case EXPR_SUBSTRING:
2235       break;
2236
2237     case EXPR_OP:
2238       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
2239       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
2240       break;
2241
2242     case EXPR_FUNCTION:
2243       for (actual = expr->value.function.actual; actual; actual = actual->next)
2244         gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
2245
2246       if (expr->value.function.esym == NULL
2247             && expr->value.function.isym != NULL
2248             && expr->value.function.actual->expr->symtree
2249             && gfc_map_intrinsic_function (expr, mapping))
2250         break;
2251
2252       for (sym = mapping->syms; sym; sym = sym->next)
2253         if (sym->old == expr->value.function.esym)
2254           {
2255             expr->value.function.esym = sym->new_sym->n.sym;
2256             gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
2257             expr->value.function.esym->result = sym->new_sym->n.sym;
2258           }
2259       break;
2260
2261     case EXPR_ARRAY:
2262     case EXPR_STRUCTURE:
2263       gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
2264       break;
2265
2266     case EXPR_COMPCALL:
2267     case EXPR_PPC:
2268       gcc_unreachable ();
2269       break;
2270     }
2271
2272   return;
2273 }
2274
2275
2276 /* Evaluate interface expression EXPR using MAPPING.  Store the result
2277    in SE.  */
2278
2279 void
2280 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
2281                              gfc_se * se, gfc_expr * expr)
2282 {
2283   expr = gfc_copy_expr (expr);
2284   gfc_apply_interface_mapping_to_expr (mapping, expr);
2285   gfc_conv_expr (se, expr);
2286   se->expr = gfc_evaluate_now (se->expr, &se->pre);
2287   gfc_free_expr (expr);
2288 }
2289
2290
2291 /* Returns a reference to a temporary array into which a component of
2292    an actual argument derived type array is copied and then returned
2293    after the function call.  */
2294 void
2295 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr,
2296                            int g77, sym_intent intent)
2297 {
2298   gfc_se lse;
2299   gfc_se rse;
2300   gfc_ss *lss;
2301   gfc_ss *rss;
2302   gfc_loopinfo loop;
2303   gfc_loopinfo loop2;
2304   gfc_ss_info *info;
2305   tree offset;
2306   tree tmp_index;
2307   tree tmp;
2308   tree base_type;
2309   stmtblock_t body;
2310   int n;
2311
2312   gcc_assert (expr->expr_type == EXPR_VARIABLE);
2313
2314   gfc_init_se (&lse, NULL);
2315   gfc_init_se (&rse, NULL);
2316
2317   /* Walk the argument expression.  */
2318   rss = gfc_walk_expr (expr);
2319
2320   gcc_assert (rss != gfc_ss_terminator);
2321  
2322   /* Initialize the scalarizer.  */
2323   gfc_init_loopinfo (&loop);
2324   gfc_add_ss_to_loop (&loop, rss);
2325
2326   /* Calculate the bounds of the scalarization.  */
2327   gfc_conv_ss_startstride (&loop);
2328
2329   /* Build an ss for the temporary.  */
2330   if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
2331     gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
2332
2333   base_type = gfc_typenode_for_spec (&expr->ts);
2334   if (GFC_ARRAY_TYPE_P (base_type)
2335                 || GFC_DESCRIPTOR_TYPE_P (base_type))
2336     base_type = gfc_get_element_type (base_type);
2337
2338   loop.temp_ss = gfc_get_ss ();;
2339   loop.temp_ss->type = GFC_SS_TEMP;
2340   loop.temp_ss->data.temp.type = base_type;
2341
2342   if (expr->ts.type == BT_CHARACTER)
2343     loop.temp_ss->string_length = expr->ts.u.cl->backend_decl;
2344   else
2345     loop.temp_ss->string_length = NULL;
2346
2347   parmse->string_length = loop.temp_ss->string_length;
2348   loop.temp_ss->data.temp.dimen = loop.dimen;
2349   loop.temp_ss->next = gfc_ss_terminator;
2350
2351   /* Associate the SS with the loop.  */
2352   gfc_add_ss_to_loop (&loop, loop.temp_ss);
2353
2354   /* Setup the scalarizing loops.  */
2355   gfc_conv_loop_setup (&loop, &expr->where);
2356
2357   /* Pass the temporary descriptor back to the caller.  */
2358   info = &loop.temp_ss->data.info;
2359   parmse->expr = info->descriptor;
2360
2361   /* Setup the gfc_se structures.  */
2362   gfc_copy_loopinfo_to_se (&lse, &loop);
2363   gfc_copy_loopinfo_to_se (&rse, &loop);
2364
2365   rse.ss = rss;
2366   lse.ss = loop.temp_ss;
2367   gfc_mark_ss_chain_used (rss, 1);
2368   gfc_mark_ss_chain_used (loop.temp_ss, 1);
2369
2370   /* Start the scalarized loop body.  */
2371   gfc_start_scalarized_body (&loop, &body);
2372
2373   /* Translate the expression.  */
2374   gfc_conv_expr (&rse, expr);
2375
2376   gfc_conv_tmp_array_ref (&lse);
2377   gfc_advance_se_ss_chain (&lse);
2378
2379   if (intent != INTENT_OUT)
2380     {
2381       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false);
2382       gfc_add_expr_to_block (&body, tmp);
2383       gcc_assert (rse.ss == gfc_ss_terminator);
2384       gfc_trans_scalarizing_loops (&loop, &body);
2385     }
2386   else
2387     {
2388       /* Make sure that the temporary declaration survives by merging
2389        all the loop declarations into the current context.  */
2390       for (n = 0; n < loop.dimen; n++)
2391         {
2392           gfc_merge_block_scope (&body);
2393           body = loop.code[loop.order[n]];
2394         }
2395       gfc_merge_block_scope (&body);
2396     }
2397
2398   /* Add the post block after the second loop, so that any
2399      freeing of allocated memory is done at the right time.  */
2400   gfc_add_block_to_block (&parmse->pre, &loop.pre);
2401
2402   /**********Copy the temporary back again.*********/
2403
2404   gfc_init_se (&lse, NULL);
2405   gfc_init_se (&rse, NULL);
2406
2407   /* Walk the argument expression.  */
2408   lss = gfc_walk_expr (expr);
2409   rse.ss = loop.temp_ss;
2410   lse.ss = lss;
2411
2412   /* Initialize the scalarizer.  */
2413   gfc_init_loopinfo (&loop2);
2414   gfc_add_ss_to_loop (&loop2, lss);
2415
2416   /* Calculate the bounds of the scalarization.  */
2417   gfc_conv_ss_startstride (&loop2);
2418
2419   /* Setup the scalarizing loops.  */
2420   gfc_conv_loop_setup (&loop2, &expr->where);
2421
2422   gfc_copy_loopinfo_to_se (&lse, &loop2);
2423   gfc_copy_loopinfo_to_se (&rse, &loop2);
2424
2425   gfc_mark_ss_chain_used (lss, 1);
2426   gfc_mark_ss_chain_used (loop.temp_ss, 1);
2427
2428   /* Declare the variable to hold the temporary offset and start the
2429      scalarized loop body.  */
2430   offset = gfc_create_var (gfc_array_index_type, NULL);
2431   gfc_start_scalarized_body (&loop2, &body);
2432
2433   /* Build the offsets for the temporary from the loop variables.  The
2434      temporary array has lbounds of zero and strides of one in all
2435      dimensions, so this is very simple.  The offset is only computed
2436      outside the innermost loop, so the overall transfer could be
2437      optimized further.  */
2438   info = &rse.ss->data.info;
2439
2440   tmp_index = gfc_index_zero_node;
2441   for (n = info->dimen - 1; n > 0; n--)
2442     {
2443       tree tmp_str;
2444       tmp = rse.loop->loopvar[n];
2445       tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2446                          tmp, rse.loop->from[n]);
2447       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2448                          tmp, tmp_index);
2449
2450       tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2451                              rse.loop->to[n-1], rse.loop->from[n-1]);
2452       tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2453                              tmp_str, gfc_index_one_node);
2454
2455       tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
2456                                tmp, tmp_str);
2457     }
2458
2459   tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2460                            tmp_index, rse.loop->from[0]);
2461   gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
2462
2463   tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2464                            rse.loop->loopvar[0], offset);
2465
2466   /* Now use the offset for the reference.  */
2467   tmp = build_fold_indirect_ref_loc (input_location,
2468                                  info->data);
2469   rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
2470
2471   if (expr->ts.type == BT_CHARACTER)
2472     rse.string_length = expr->ts.u.cl->backend_decl;
2473
2474   gfc_conv_expr (&lse, expr);
2475
2476   gcc_assert (lse.ss == gfc_ss_terminator);
2477
2478   tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
2479   gfc_add_expr_to_block (&body, tmp);
2480   
2481   /* Generate the copying loops.  */
2482   gfc_trans_scalarizing_loops (&loop2, &body);
2483
2484   /* Wrap the whole thing up by adding the second loop to the post-block
2485      and following it by the post-block of the first loop.  In this way,
2486      if the temporary needs freeing, it is done after use!  */
2487   if (intent != INTENT_IN)
2488     {
2489       gfc_add_block_to_block (&parmse->post, &loop2.pre);
2490       gfc_add_block_to_block (&parmse->post, &loop2.post);
2491     }
2492
2493   gfc_add_block_to_block (&parmse->post, &loop.post);
2494
2495   gfc_cleanup_loop (&loop);
2496   gfc_cleanup_loop (&loop2);
2497
2498   /* Pass the string length to the argument expression.  */
2499   if (expr->ts.type == BT_CHARACTER)
2500     parmse->string_length = expr->ts.u.cl->backend_decl;
2501
2502   /* We want either the address for the data or the address of the descriptor,
2503      depending on the mode of passing array arguments.  */
2504   if (g77)
2505     parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
2506   else
2507     parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
2508
2509   return;
2510 }
2511
2512
2513 /* Generate the code for argument list functions.  */
2514
2515 static void
2516 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
2517 {
2518   /* Pass by value for g77 %VAL(arg), pass the address
2519      indirectly for %LOC, else by reference.  Thus %REF
2520      is a "do-nothing" and %LOC is the same as an F95
2521      pointer.  */
2522   if (strncmp (name, "%VAL", 4) == 0)
2523     gfc_conv_expr (se, expr);
2524   else if (strncmp (name, "%LOC", 4) == 0)
2525     {
2526       gfc_conv_expr_reference (se, expr);
2527       se->expr = gfc_build_addr_expr (NULL, se->expr);
2528     }
2529   else if (strncmp (name, "%REF", 4) == 0)
2530     gfc_conv_expr_reference (se, expr);
2531   else
2532     gfc_error ("Unknown argument list function at %L", &expr->where);
2533 }
2534
2535
2536 /* Generate code for a procedure call.  Note can return se->post != NULL.
2537    If se->direct_byref is set then se->expr contains the return parameter.
2538    Return nonzero, if the call has alternate specifiers.
2539    'expr' is only needed for procedure pointer components.  */
2540
2541 int
2542 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
2543                          gfc_actual_arglist * arg, gfc_expr * expr,
2544                          tree append_args)
2545 {
2546   gfc_interface_mapping mapping;
2547   tree arglist;
2548   tree retargs;
2549   tree tmp;
2550   tree fntype;
2551   gfc_se parmse;
2552   gfc_ss *argss;
2553   gfc_ss_info *info;
2554   int byref;
2555   int parm_kind;
2556   tree type;
2557   tree var;
2558   tree len;
2559   tree stringargs;
2560   gfc_formal_arglist *formal;
2561   int has_alternate_specifier = 0;
2562   bool need_interface_mapping;
2563   bool callee_alloc;
2564   gfc_typespec ts;
2565   gfc_charlen cl;
2566   gfc_expr *e;
2567   gfc_symbol *fsym;
2568   stmtblock_t post;
2569   enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
2570   gfc_component *comp = NULL;
2571
2572   arglist = NULL_TREE;
2573   retargs = NULL_TREE;
2574   stringargs = NULL_TREE;
2575   var = NULL_TREE;
2576   len = NULL_TREE;
2577   gfc_clear_ts (&ts);
2578
2579   if (sym->from_intmod == INTMOD_ISO_C_BINDING)
2580     {
2581       if (sym->intmod_sym_id == ISOCBINDING_LOC)
2582         {
2583           if (arg->expr->rank == 0)
2584             gfc_conv_expr_reference (se, arg->expr);
2585           else
2586             {
2587               int f;
2588               /* This is really the actual arg because no formal arglist is
2589                  created for C_LOC.      */
2590               fsym = arg->expr->symtree->n.sym;
2591
2592               /* We should want it to do g77 calling convention.  */
2593               f = (fsym != NULL)
2594                 && !(fsym->attr.pointer || fsym->attr.allocatable)
2595                 && fsym->as->type != AS_ASSUMED_SHAPE;
2596               f = f || !sym->attr.always_explicit;
2597           
2598               argss = gfc_walk_expr (arg->expr);
2599               gfc_conv_array_parameter (se, arg->expr, argss, f,
2600                                         NULL, NULL, NULL);
2601             }
2602
2603           /* TODO -- the following two lines shouldn't be necessary, but
2604             they're removed a bug is exposed later in the codepath.
2605             This is workaround was thus introduced, but will have to be
2606             removed; please see PR 35150 for details about the issue.  */
2607           se->expr = convert (pvoid_type_node, se->expr);
2608           se->expr = gfc_evaluate_now (se->expr, &se->pre);
2609
2610           return 0;
2611         }
2612       else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
2613         {
2614           arg->expr->ts.type = sym->ts.u.derived->ts.type;
2615           arg->expr->ts.f90_type = sym->ts.u.derived->ts.f90_type;
2616           arg->expr->ts.kind = sym->ts.u.derived->ts.kind;
2617           gfc_conv_expr_reference (se, arg->expr);
2618       
2619           return 0;
2620         }
2621       else if ((sym->intmod_sym_id == ISOCBINDING_F_POINTER
2622                  && arg->next->expr->rank == 0)
2623                || sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)
2624         {
2625           /* Convert c_f_pointer if fptr is a scalar
2626              and convert c_f_procpointer.  */
2627           gfc_se cptrse;
2628           gfc_se fptrse;
2629
2630           gfc_init_se (&cptrse, NULL);
2631           gfc_conv_expr (&cptrse, arg->expr);
2632           gfc_add_block_to_block (&se->pre, &cptrse.pre);
2633           gfc_add_block_to_block (&se->post, &cptrse.post);
2634
2635           gfc_init_se (&fptrse, NULL);
2636           if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
2637               || gfc_is_proc_ptr_comp (arg->next->expr, NULL))
2638             fptrse.want_pointer = 1;
2639
2640           gfc_conv_expr (&fptrse, arg->next->expr);
2641           gfc_add_block_to_block (&se->pre, &fptrse.pre);
2642           gfc_add_block_to_block (&se->post, &fptrse.post);
2643
2644           if (gfc_is_proc_ptr_comp (arg->next->expr, NULL))
2645             tmp = gfc_get_ppc_type (arg->next->expr->ref->u.c.component);
2646           else
2647             tmp = TREE_TYPE (arg->next->expr->symtree->n.sym->backend_decl);
2648           se->expr = fold_build2 (MODIFY_EXPR, tmp, fptrse.expr,
2649                                   fold_convert (tmp, cptrse.expr));
2650
2651           return 0;
2652         }
2653       else if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
2654         {
2655           gfc_se arg1se;
2656           gfc_se arg2se;
2657
2658           /* Build the addr_expr for the first argument.  The argument is
2659              already an *address* so we don't need to set want_pointer in
2660              the gfc_se.  */
2661           gfc_init_se (&arg1se, NULL);
2662           gfc_conv_expr (&arg1se, arg->expr);
2663           gfc_add_block_to_block (&se->pre, &arg1se.pre);
2664           gfc_add_block_to_block (&se->post, &arg1se.post);
2665
2666           /* See if we were given two arguments.  */
2667           if (arg->next == NULL)
2668             /* Only given one arg so generate a null and do a
2669                not-equal comparison against the first arg.  */
2670             se->expr = fold_build2 (NE_EXPR, boolean_type_node, arg1se.expr,
2671                                     fold_convert (TREE_TYPE (arg1se.expr),
2672                                                   null_pointer_node));
2673           else
2674             {
2675               tree eq_expr;
2676               tree not_null_expr;
2677               
2678               /* Given two arguments so build the arg2se from second arg.  */
2679               gfc_init_se (&arg2se, NULL);
2680               gfc_conv_expr (&arg2se, arg->next->expr);
2681               gfc_add_block_to_block (&se->pre, &arg2se.pre);
2682               gfc_add_block_to_block (&se->post, &arg2se.post);
2683
2684               /* Generate test to compare that the two args are equal.  */
2685               eq_expr = fold_build2 (EQ_EXPR, boolean_type_node,
2686                                      arg1se.expr, arg2se.expr);
2687               /* Generate test to ensure that the first arg is not null.  */
2688               not_null_expr = fold_build2 (NE_EXPR, boolean_type_node,
2689                                            arg1se.expr, null_pointer_node);
2690
2691               /* Finally, the generated test must check that both arg1 is not
2692                  NULL and that it is equal to the second arg.  */
2693               se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2694                                       not_null_expr, eq_expr);
2695             }
2696
2697           return 0;
2698         }
2699     }
2700
2701   gfc_is_proc_ptr_comp (expr, &comp);
2702
2703   if (se->ss != NULL)
2704     {
2705       if (!sym->attr.elemental)
2706         {
2707           gcc_assert (se->ss->type == GFC_SS_FUNCTION);
2708           if (se->ss->useflags)
2709             {
2710               gcc_assert ((!comp && gfc_return_by_reference (sym)
2711                            && sym->result->attr.dimension)
2712                           || (comp && comp->attr.dimension));
2713               gcc_assert (se->loop != NULL);
2714
2715               /* Access the previously obtained result.  */
2716               gfc_conv_tmp_array_ref (se);
2717               gfc_advance_se_ss_chain (se);
2718               return 0;
2719             }
2720         }
2721       info = &se->ss->data.info;
2722     }
2723   else
2724     info = NULL;
2725
2726   gfc_init_block (&post);
2727   gfc_init_interface_mapping (&mapping);
2728   if (!comp)
2729     {
2730       formal = sym->formal;
2731       need_interface_mapping = sym->attr.dimension ||
2732                                (sym->ts.type == BT_CHARACTER
2733                                 && sym->ts.u.cl->length
2734                                 && sym->ts.u.cl->length->expr_type
2735                                    != EXPR_CONSTANT);
2736     }
2737   else
2738     {
2739       formal = comp->formal;
2740       need_interface_mapping = comp->attr.dimension ||
2741                                (comp->ts.type == BT_CHARACTER
2742                                 && comp->ts.u.cl->length
2743                                 && comp->ts.u.cl->length->expr_type
2744                                    != EXPR_CONSTANT);
2745     }
2746
2747   /* Evaluate the arguments.  */
2748   for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
2749     {
2750       e = arg->expr;
2751       fsym = formal ? formal->sym : NULL;
2752       parm_kind = MISSING;
2753       if (e == NULL)
2754         {
2755
2756           if (se->ignore_optional)
2757             {
2758               /* Some intrinsics have already been resolved to the correct
2759                  parameters.  */
2760               continue;
2761             }
2762           else if (arg->label)
2763             {
2764               has_alternate_specifier = 1;
2765               continue;
2766             }
2767           else
2768             {
2769               /* Pass a NULL pointer for an absent arg.  */
2770               gfc_init_se (&parmse, NULL);
2771               parmse.expr = null_pointer_node;
2772               if (arg->missing_arg_type == BT_CHARACTER)
2773                 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
2774             }
2775         }
2776       else if (fsym && fsym->ts.type == BT_CLASS
2777                  && e->ts.type == BT_DERIVED)
2778         {
2779           tree data;
2780           tree vindex;
2781           tree size;
2782
2783           /* The derived type needs to be converted to a temporary
2784              CLASS object.  */
2785           gfc_init_se (&parmse, se);
2786           type = gfc_typenode_for_spec (&fsym->ts);
2787           var = gfc_create_var (type, "class");
2788
2789           /* Get the components.  */
2790           tmp = fsym->ts.u.derived->components->backend_decl;
2791           data = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
2792                               var, tmp, NULL_TREE);
2793           tmp = fsym->ts.u.derived->components->next->backend_decl;
2794           vindex = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
2795                                 var, tmp, NULL_TREE);
2796           tmp = fsym->ts.u.derived->components->next->next->backend_decl;
2797           size = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
2798                               var, tmp, NULL_TREE);
2799
2800           /* Set the vindex.  */
2801           tmp = build_int_cst (TREE_TYPE (vindex), e->ts.u.derived->vindex);
2802           gfc_add_modify (&parmse.pre, vindex, tmp);
2803
2804           /* Set the size.  */
2805           tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&e->ts));
2806           gfc_add_modify (&parmse.pre, size,
2807                           fold_convert (TREE_TYPE (size), tmp));
2808
2809           /* Now set the data field.  */
2810           argss = gfc_walk_expr (e);
2811           if (argss == gfc_ss_terminator)
2812             {
2813               gfc_conv_expr_reference (&parmse, e);
2814               tmp = fold_convert (TREE_TYPE (data),
2815                                   parmse.expr);
2816               gfc_add_modify (&parmse.pre, data, tmp);
2817             }
2818           else
2819             {
2820               gfc_conv_expr (&parmse, e);
2821               gfc_add_modify (&parmse.pre, data, parmse.expr);
2822             }
2823
2824           /* Pass the address of the class object.  */
2825           parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
2826         }
2827       else if (se->ss && se->ss->useflags)
2828         {
2829           /* An elemental function inside a scalarized loop.  */
2830           gfc_init_se (&parmse, se);
2831           gfc_conv_expr_reference (&parmse, e);
2832           parm_kind = ELEMENTAL;
2833         }
2834       else
2835         {
2836           /* A scalar or transformational function.  */
2837           gfc_init_se (&parmse, NULL);
2838           argss = gfc_walk_expr (e);
2839
2840           if (argss == gfc_ss_terminator)
2841             {
2842               if (e->expr_type == EXPR_VARIABLE
2843                     && e->symtree->n.sym->attr.cray_pointee
2844                     && fsym && fsym->attr.flavor == FL_PROCEDURE)
2845                 {
2846                     /* The Cray pointer needs to be converted to a pointer to
2847                        a type given by the expression.  */
2848                     gfc_conv_expr (&parmse, e);
2849                     type = build_pointer_type (TREE_TYPE (parmse.expr));
2850                     tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
2851                     parmse.expr = convert (type, tmp);
2852                 }
2853               else if (fsym && fsym->attr.value)
2854                 {
2855                   if (fsym->ts.type == BT_CHARACTER
2856                       && fsym->ts.is_c_interop
2857                       && fsym->ns->proc_name != NULL
2858                       && fsym->ns->proc_name->attr.is_bind_c)
2859                     {
2860                       parmse.expr = NULL;
2861                       gfc_conv_scalar_char_value (fsym, &parmse, &e);
2862                       if (parmse.expr == NULL)
2863                         gfc_conv_expr (&parmse, e);
2864                     }
2865                   else
2866                     gfc_conv_expr (&parmse, e);
2867                 }
2868               else if (arg->name && arg->name[0] == '%')
2869                 /* Argument list functions %VAL, %LOC and %REF are signalled
2870                    through arg->name.  */
2871                 conv_arglist_function (&parmse, arg->expr, arg->name);
2872               else if ((e->expr_type == EXPR_FUNCTION)
2873                         && ((e->value.function.esym
2874                              && e->value.function.esym->result->attr.pointer)
2875                             || (!e->value.function.esym
2876                                 && e->symtree->n.sym->attr.pointer))
2877                         && fsym && fsym->attr.target)
2878                 {
2879                   gfc_conv_expr (&parmse, e);
2880                   parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2881                 }
2882               else if (e->expr_type == EXPR_FUNCTION
2883                        && e->symtree->n.sym->result
2884                        && e->symtree->n.sym->result != e->symtree->n.sym
2885                        && e->symtree->n.sym->result->attr.proc_pointer)
2886                 {
2887                   /* Functions returning procedure pointers.  */
2888                   gfc_conv_expr (&parmse, e);
2889                   if (fsym && fsym->attr.proc_pointer)
2890                     parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2891                 }
2892               else
2893                 {
2894                   gfc_conv_expr_reference (&parmse, e);
2895                   if (fsym && e->expr_type != EXPR_NULL
2896                       && ((fsym->attr.pointer
2897                            && fsym->attr.flavor != FL_PROCEDURE)
2898                           || (fsym->attr.proc_pointer
2899                               && !(e->expr_type == EXPR_VARIABLE
2900                               && e->symtree->n.sym->attr.dummy))
2901                           || (e->expr_type == EXPR_VARIABLE
2902                               && gfc_is_proc_ptr_comp (e, NULL))))
2903                     {
2904                       /* Scalar pointer dummy args require an extra level of
2905                          indirection. The null pointer already contains
2906                          this level of indirection.  */
2907                       parm_kind = SCALAR_POINTER;
2908                       parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2909                     }
2910                 }
2911             }
2912           else
2913             {
2914               /* If the procedure requires an explicit interface, the actual
2915                  argument is passed according to the corresponding formal
2916                  argument.  If the corresponding formal argument is a POINTER,
2917                  ALLOCATABLE or assumed shape, we do not use g77's calling
2918                  convention, and pass the address of the array descriptor
2919                  instead. Otherwise we use g77's calling convention.  */
2920               int f;
2921               f = (fsym != NULL)
2922                   && !(fsym->attr.pointer || fsym->attr.allocatable)
2923                   && fsym->as->type != AS_ASSUMED_SHAPE;
2924               f = f || !sym->attr.always_explicit;
2925
2926               if (e->expr_type == EXPR_VARIABLE
2927                     && is_subref_array (e))
2928                 /* The actual argument is a component reference to an
2929                    array of derived types.  In this case, the argument
2930                    is converted to a temporary, which is passed and then
2931                    written back after the procedure call.  */
2932                 gfc_conv_subref_array_arg (&parmse, e, f,
2933                         fsym ? fsym->attr.intent : INTENT_INOUT);
2934               else
2935                 gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
2936                                           sym->name, NULL);
2937
2938               /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 
2939                  allocated on entry, it must be deallocated.  */
2940               if (fsym && fsym->attr.allocatable
2941                   && fsym->attr.intent == INTENT_OUT)
2942                 {
2943                   tmp = build_fold_indirect_ref_loc (input_location,
2944                                                  parmse.expr);
2945                   tmp = gfc_trans_dealloc_allocated (tmp);
2946                   gfc_add_expr_to_block (&se->pre, tmp);
2947                 }
2948
2949             } 
2950         }
2951
2952       /* The case with fsym->attr.optional is that of a user subroutine
2953          with an interface indicating an optional argument.  When we call
2954          an intrinsic subroutine, however, fsym is NULL, but we might still
2955          have an optional argument, so we proceed to the substitution
2956          just in case.  */
2957       if (e && (fsym == NULL || fsym->attr.optional))
2958         {
2959           /* If an optional argument is itself an optional dummy argument,
2960              check its presence and substitute a null if absent.  */
2961           if (e->expr_type == EXPR_VARIABLE
2962               && e->symtree->n.sym->attr.optional)
2963             gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
2964                                     e->representation.length);
2965         }
2966
2967       if (fsym && e)
2968         {
2969           /* Obtain the character length of an assumed character length
2970              length procedure from the typespec.  */
2971           if (fsym->ts.type == BT_CHARACTER
2972               && parmse.string_length == NULL_TREE
2973               && e->ts.type == BT_PROCEDURE
2974               && e->symtree->n.sym->ts.type == BT_CHARACTER
2975               && e->symtree->n.sym->ts.u.cl->length != NULL
2976               && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
2977             {
2978               gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
2979               parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
2980             }
2981         }
2982
2983       if (fsym && need_interface_mapping && e)
2984         gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
2985
2986       gfc_add_block_to_block (&se->pre, &parmse.pre);
2987       gfc_add_block_to_block (&post, &parmse.post);
2988
2989       /* Allocated allocatable components of derived types must be
2990          deallocated for non-variable scalars.  Non-variable arrays are
2991          dealt with in trans-array.c(gfc_conv_array_parameter).  */
2992       if (e && e->ts.type == BT_DERIVED
2993             && e->ts.u.derived->attr.alloc_comp
2994             && !(e->symtree && e->symtree->n.sym->attr.pointer)
2995             && (e->expr_type != EXPR_VARIABLE && !e->rank))
2996         {
2997           int parm_rank;
2998           tmp = build_fold_indirect_ref_loc (input_location,
2999                                          parmse.expr);
3000           parm_rank = e->rank;
3001           switch (parm_kind)
3002             {
3003             case (ELEMENTAL):
3004             case (SCALAR):
3005               parm_rank = 0;
3006               break;
3007
3008             case (SCALAR_POINTER):
3009               tmp = build_fold_indirect_ref_loc (input_location,
3010                                              tmp);
3011               break;
3012             }
3013
3014           if (e->expr_type == EXPR_OP
3015                 && e->value.op.op == INTRINSIC_PARENTHESES
3016                 && e->value.op.op1->expr_type == EXPR_VARIABLE)
3017             {
3018               tree local_tmp;
3019               local_tmp = gfc_evaluate_now (tmp, &se->pre);
3020               local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
3021               gfc_add_expr_to_block (&se->post, local_tmp);
3022             }
3023
3024           tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
3025
3026           gfc_add_expr_to_block (&se->post, tmp);
3027         }
3028
3029       /* Add argument checking of passing an unallocated/NULL actual to
3030          a nonallocatable/nonpointer dummy.  */
3031
3032       if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
3033         {
3034           symbol_attribute *attr;
3035           char *msg;
3036           tree cond;
3037
3038           if (e->expr_type == EXPR_VARIABLE)
3039             attr = &e->symtree->n.sym->attr;
3040           else if (e->expr_type == EXPR_FUNCTION)
3041             {
3042               /* For intrinsic functions, the gfc_attr are not available.  */
3043               if (e->symtree->n.sym->attr.generic && e->value.function.isym)
3044                 goto end_pointer_check;
3045
3046               if (e->symtree->n.sym->attr.generic)
3047                 attr = &e->value.function.esym->attr;
3048               else
3049                 attr = &e->symtree->n.sym->result->attr;
3050             }
3051           else
3052             goto end_pointer_check;
3053
3054           if (attr->optional)
3055             {
3056               /* If the actual argument is an optional pointer/allocatable and
3057                  the formal argument takes an nonpointer optional value,
3058                  it is invalid to pass a non-present argument on, even
3059                  though there is no technical reason for this in gfortran.
3060                  See Fortran 2003, Section 12.4.1.6 item (7)+(8).  */
3061               tree present, nullptr, type;
3062
3063               if (attr->allocatable
3064                   && (fsym == NULL || !fsym->attr.allocatable))
3065                 asprintf (&msg, "Allocatable actual argument '%s' is not "
3066                           "allocated or not present", e->symtree->n.sym->name);
3067               else if (attr->pointer
3068                        && (fsym == NULL || !fsym->attr.pointer))
3069                 asprintf (&msg, "Pointer actual argument '%s' is not "
3070                           "associated or not present",
3071                           e->symtree->n.sym->name);
3072               else if (attr->proc_pointer
3073                        && (fsym == NULL || !fsym->attr.proc_pointer))
3074                 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3075                           "associated or not present",
3076                           e->symtree->n.sym->name);
3077               else
3078                 goto end_pointer_check;
3079
3080               present = gfc_conv_expr_present (e->symtree->n.sym);
3081               type = TREE_TYPE (present);
3082               present = fold_build2 (EQ_EXPR, boolean_type_node, present,
3083                                      fold_convert (type, null_pointer_node));
3084               type = TREE_TYPE (parmse.expr);
3085               nullptr = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3086                                      fold_convert (type, null_pointer_node));
3087               cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node,
3088                                   present, nullptr);
3089             }
3090           else
3091             {
3092               if (attr->allocatable
3093                   && (fsym == NULL || !fsym->attr.allocatable))
3094                 asprintf (&msg, "Allocatable actual argument '%s' is not "
3095                       "allocated", e->symtree->n.sym->name);
3096               else if (attr->pointer
3097                        && (fsym == NULL || !fsym->attr.pointer))
3098                 asprintf (&msg, "Pointer actual argument '%s' is not "
3099                       "associated", e->symtree->n.sym->name);
3100               else if (attr->proc_pointer
3101                        && (fsym == NULL || !fsym->attr.proc_pointer))
3102                 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3103                       "associated", e->symtree->n.sym->name);
3104               else
3105                 goto end_pointer_check;
3106
3107
3108               cond = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3109                                   fold_convert (TREE_TYPE (parmse.expr),
3110                                                 null_pointer_node));
3111             }
3112  
3113           gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
3114                                    msg);
3115           gfc_free (msg);
3116         }
3117       end_pointer_check:
3118
3119
3120       /* Character strings are passed as two parameters, a length and a
3121          pointer - except for Bind(c) which only passes the pointer.  */
3122       if (parmse.string_length != NULL_TREE && !sym->attr.is_bind_c)
3123         stringargs = gfc_chainon_list (stringargs, parmse.string_length);
3124
3125       arglist = gfc_chainon_list (arglist, parmse.expr);
3126     }
3127   gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
3128
3129   if (comp)
3130     ts = comp->ts;
3131   else
3132    ts = sym->ts;
3133
3134   if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
3135     se->string_length = build_int_cst (gfc_charlen_type_node, 1);
3136   else if (ts.type == BT_CHARACTER)
3137     {
3138       if (ts.u.cl->length == NULL)
3139         {
3140           /* Assumed character length results are not allowed by 5.1.1.5 of the
3141              standard and are trapped in resolve.c; except in the case of SPREAD
3142              (and other intrinsics?) and dummy functions.  In the case of SPREAD,
3143              we take the character length of the first argument for the result.
3144              For dummies, we have to look through the formal argument list for
3145              this function and use the character length found there.*/
3146           if (!sym->attr.dummy)
3147             cl.backend_decl = TREE_VALUE (stringargs);
3148           else
3149             {
3150               formal = sym->ns->proc_name->formal;
3151               for (; formal; formal = formal->next)
3152                 if (strcmp (formal->sym->name, sym->name) == 0)
3153                   cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
3154             }
3155         }
3156         else
3157         {
3158           tree tmp;
3159
3160           /* Calculate the length of the returned string.  */
3161           gfc_init_se (&parmse, NULL);
3162           if (need_interface_mapping)
3163             gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
3164           else
3165             gfc_conv_expr (&parmse, ts.u.cl->length);
3166           gfc_add_block_to_block (&se->pre, &parmse.pre);
3167           gfc_add_block_to_block (&se->post, &parmse.post);
3168           
3169           tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
3170           tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
3171                              build_int_cst (gfc_charlen_type_node, 0));
3172           cl.backend_decl = tmp;
3173         }
3174
3175       /* Set up a charlen structure for it.  */
3176       cl.next = NULL;
3177       cl.length = NULL;
3178       ts.u.cl = &cl;
3179
3180       len = cl.backend_decl;
3181     }
3182
3183   byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
3184           || (!comp && gfc_return_by_reference (sym));
3185   if (byref)
3186     {
3187       if (se->direct_byref)
3188         {
3189           /* Sometimes, too much indirection can be applied; e.g. for
3190              function_result = array_valued_recursive_function.  */
3191           if (TREE_TYPE (TREE_TYPE (se->expr))
3192                 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
3193                 && GFC_DESCRIPTOR_TYPE_P
3194                         (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
3195             se->expr = build_fold_indirect_ref_loc (input_location,
3196                                                 se->expr);
3197
3198           retargs = gfc_chainon_list (retargs, se->expr);
3199         }
3200       else if (comp && comp->attr.dimension)
3201         {
3202           gcc_assert (se->loop && info);
3203
3204           /* Set the type of the array.  */
3205           tmp = gfc_typenode_for_spec (&comp->ts);
3206           info->dimen = se->loop->dimen;
3207
3208           /* Evaluate the bounds of the result, if known.  */
3209           gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
3210
3211           /* Create a temporary to store the result.  In case the function
3212              returns a pointer, the temporary will be a shallow copy and
3213              mustn't be deallocated.  */
3214           callee_alloc = comp->attr.allocatable || comp->attr.pointer;
3215           gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
3216                                        NULL_TREE, false, !comp->attr.pointer,
3217                                        callee_alloc, &se->ss->expr->where);
3218
3219           /* Pass the temporary as the first argument.  */
3220           tmp = info->descriptor;
3221           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3222           retargs = gfc_chainon_list (retargs, tmp);
3223         }
3224       else if (!comp && sym->result->attr.dimension)
3225         {
3226           gcc_assert (se->loop && info);
3227
3228           /* Set the type of the array.  */
3229           tmp = gfc_typenode_for_spec (&ts);
3230           info->dimen = se->loop->dimen;
3231
3232           /* Evaluate the bounds of the result, if known.  */
3233           gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
3234
3235           /* Create a temporary to store the result.  In case the function
3236              returns a pointer, the temporary will be a shallow copy and
3237              mustn't be deallocated.  */
3238           callee_alloc = sym->attr.allocatable || sym->attr.pointer;
3239           gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
3240                                        NULL_TREE, false, !sym->attr.pointer,
3241                                        callee_alloc, &se->ss->expr->where);
3242
3243           /* Pass the temporary as the first argument.  */
3244           tmp = info->descriptor;
3245           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3246           retargs = gfc_chainon_list (retargs, tmp);
3247         }
3248       else if (ts.type == BT_CHARACTER)
3249         {
3250           /* Pass the string length.  */
3251           type = gfc_get_character_type (ts.kind, ts.u.cl);
3252           type = build_pointer_type (type);
3253
3254           /* Return an address to a char[0:len-1]* temporary for
3255              character pointers.  */
3256           if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3257                || (comp && (comp->attr.pointer || comp->attr.allocatable)))
3258             {
3259               var = gfc_create_var (type, "pstr");
3260
3261               /* Provide an address expression for the function arguments.  */
3262               var = gfc_build_addr_expr (NULL_TREE, var);
3263             }
3264           else
3265             var = gfc_conv_string_tmp (se, type, len);
3266
3267           retargs = gfc_chainon_list (retargs, var);
3268         }
3269       else
3270         {
3271           gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
3272
3273           type = gfc_get_complex_type (ts.kind);
3274           var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
3275           retargs = gfc_chainon_list (retargs, var);
3276         }
3277
3278       /* Add the string length to the argument list.  */
3279       if (ts.type == BT_CHARACTER)
3280         retargs = gfc_chainon_list (retargs, len);
3281     }
3282   gfc_free_interface_mapping (&mapping);
3283
3284   /* Add the return arguments.  */
3285   arglist = chainon (retargs, arglist);
3286
3287   /* Add the hidden string length parameters to the arguments.  */
3288   arglist = chainon (arglist, stringargs);
3289
3290   /* We may want to append extra arguments here.  This is used e.g. for
3291      calls to libgfortran_matmul_??, which need extra information.  */
3292   if (append_args != NULL_TREE)
3293     arglist = chainon (arglist, append_args);
3294
3295   /* Generate the actual call.  */
3296   conv_function_val (se, sym, expr);
3297
3298   /* If there are alternate return labels, function type should be
3299      integer.  Can't modify the type in place though, since it can be shared
3300      with other functions.  For dummy arguments, the typing is done to
3301      to this result, even if it has to be repeated for each call.  */
3302   if (has_alternate_specifier
3303       && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
3304     {
3305       if (!sym->attr.dummy)
3306         {
3307           TREE_TYPE (sym->backend_decl)
3308                 = build_function_type (integer_type_node,
3309                       TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
3310           se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
3311         }
3312       else
3313         TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
3314     }
3315
3316   fntype = TREE_TYPE (TREE_TYPE (se->expr));
3317   se->expr = build_call_list (TREE_TYPE (fntype), se->expr, arglist);
3318
3319   /* If we have a pointer function, but we don't want a pointer, e.g.
3320      something like
3321         x = f()
3322      where f is pointer valued, we have to dereference the result.  */
3323   if (!se->want_pointer && !byref && sym->attr.pointer
3324       && !gfc_is_proc_ptr_comp (expr, NULL))
3325     se->expr = build_fold_indirect_ref_loc (input_location,
3326                                         se->expr);
3327
3328   /* f2c calling conventions require a scalar default real function to
3329      return a double precision result.  Convert this back to default
3330      real.  We only care about the cases that can happen in Fortran 77.
3331   */
3332   if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
3333       && sym->ts.kind == gfc_default_real_kind
3334       && !sym->attr.always_explicit)
3335     se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
3336
3337   /* A pure function may still have side-effects - it may modify its
3338      parameters.  */
3339   TREE_SIDE_EFFECTS (se->expr) = 1;
3340 #if 0
3341   if (!sym->attr.pure)
3342     TREE_SIDE_EFFECTS (se->expr) = 1;
3343 #endif
3344
3345   if (byref)
3346     {
3347       /* Add the function call to the pre chain.  There is no expression.  */
3348       gfc_add_expr_to_block (&se->pre, se->expr);
3349       se->expr = NULL_TREE;
3350
3351       if (!se->direct_byref)
3352         {
3353           if (sym->attr.dimension || (comp && comp->attr.dimension))
3354             {
3355               if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3356                 {
3357                   /* Check the data pointer hasn't been modified.  This would
3358                      happen in a function returning a pointer.  */
3359                   tmp = gfc_conv_descriptor_data_get (info->descriptor);
3360                   tmp = fold_build2 (NE_EXPR, boolean_type_node,
3361                                      tmp, info->data);
3362                   gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
3363                                            gfc_msg_fault);
3364                 }
3365               se->expr = info->descriptor;
3366               /* Bundle in the string length.  */
3367               se->string_length = len;
3368             }
3369           else if (ts.type == BT_CHARACTER)
3370             {
3371               /* Dereference for character pointer results.  */
3372               if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3373                   || (comp && (comp->attr.pointer || comp->attr.allocatable)))
3374                 se->expr = build_fold_indirect_ref_loc (input_location, var);
3375               else
3376                 se->expr = var;
3377
3378               se->string_length = len;
3379             }
3380           else
3381             {
3382               gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
3383               se->expr = build_fold_indirect_ref_loc (input_location, var);
3384             }
3385         }
3386     }
3387
3388   /* Follow the function call with the argument post block.  */
3389   if (byref)
3390     gfc_add_block_to_block (&se->pre, &post);
3391   else
3392     gfc_add_block_to_block (&se->post, &post);
3393
3394   return has_alternate_specifier;
3395 }
3396
3397
3398 /* Fill a character string with spaces.  */
3399
3400 static tree
3401 fill_with_spaces (tree start, tree type, tree size)
3402 {
3403   stmtblock_t block, loop;
3404   tree i, el, exit_label, cond, tmp;
3405
3406   /* For a simple char type, we can call memset().  */
3407   if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
3408     return build_call_expr_loc (input_location,
3409                             built_in_decls[BUILT_IN_MEMSET], 3, start,
3410                             build_int_cst (gfc_get_int_type (gfc_c_int_kind),
3411                                            lang_hooks.to_target_charset (' ')),
3412                             size);
3413
3414   /* Otherwise, we use a loop:
3415         for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
3416           *el = (type) ' ';
3417    */
3418
3419   /* Initialize variables.  */
3420   gfc_init_block (&block);
3421   i = gfc_create_var (sizetype, "i");
3422   gfc_add_modify (&block, i, fold_convert (sizetype, size));
3423   el = gfc_create_var (build_pointer_type (type), "el");
3424   gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
3425   exit_label = gfc_build_label_decl (NULL_TREE);
3426   TREE_USED (exit_label) = 1;
3427
3428
3429   /* Loop body.  */
3430   gfc_init_block (&loop);
3431
3432   /* Exit condition.  */
3433   cond = fold_build2 (LE_EXPR, boolean_type_node, i,
3434                       fold_convert (sizetype, integer_zero_node));
3435   tmp = build1_v (GOTO_EXPR, exit_label);
3436   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3437                      build_empty_stmt (input_location));
3438   gfc_add_expr_to_block (&loop, tmp);
3439
3440   /* Assignment.  */
3441   gfc_add_modify (&loop, fold_build1 (INDIRECT_REF, type, el),
3442                        build_int_cst (type,
3443                                       lang_hooks.to_target_charset (' ')));
3444
3445   /* Increment loop variables.  */
3446   gfc_add_modify (&loop, i, fold_build2 (MINUS_EXPR, sizetype, i,
3447                                               TYPE_SIZE_UNIT (type)));
3448   gfc_add_modify (&loop, el, fold_build2 (POINTER_PLUS_EXPR,
3449                                                TREE_TYPE (el), el,
3450                                                TYPE_SIZE_UNIT (type)));
3451
3452   /* Making the loop... actually loop!  */
3453   tmp = gfc_finish_block (&loop);
3454   tmp = build1_v (LOOP_EXPR, tmp);
3455   gfc_add_expr_to_block (&block, tmp);
3456
3457   /* The exit label.  */
3458   tmp = build1_v (LABEL_EXPR, exit_label);
3459   gfc_add_expr_to_block (&block, tmp);
3460
3461
3462   return gfc_finish_block (&block);
3463 }
3464
3465
3466 /* Generate code to copy a string.  */
3467
3468 void
3469 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
3470                        int dkind, tree slength, tree src, int skind)
3471 {
3472   tree tmp, dlen, slen;
3473   tree dsc;
3474   tree ssc;
3475   tree cond;
3476   tree cond2;
3477   tree tmp2;
3478   tree tmp3;
3479   tree tmp4;
3480   tree chartype;
3481   stmtblock_t tempblock;
3482
3483   gcc_assert (dkind == skind);
3484
3485   if (slength != NULL_TREE)
3486     {
3487       slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
3488       ssc = string_to_single_character (slen, src, skind);
3489     }
3490   else
3491     {
3492       slen = build_int_cst (size_type_node, 1);
3493       ssc =  src;
3494     }
3495
3496   if (dlength != NULL_TREE)
3497     {
3498       dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
3499       dsc = string_to_single_character (slen, dest, dkind);
3500     }
3501   else
3502     {
3503       dlen = build_int_cst (size_type_node, 1);
3504       dsc =  dest;
3505     }
3506
3507   if (slength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (src)))
3508     ssc = string_to_single_character (slen, src, skind);
3509   if (dlength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (dest)))
3510     dsc = string_to_single_character (dlen, dest, dkind);
3511
3512
3513   /* Assign directly if the types are compatible.  */
3514   if (dsc != NULL_TREE && ssc != NULL_TREE
3515       && TREE_TYPE (dsc) == TREE_TYPE (ssc))
3516     {
3517       gfc_add_modify (block, dsc, ssc);
3518       return;
3519     }
3520
3521   /* Do nothing if the destination length is zero.  */
3522   cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
3523                       build_int_cst (size_type_node, 0));
3524
3525   /* The following code was previously in _gfortran_copy_string:
3526
3527        // The two strings may overlap so we use memmove.
3528        void
3529        copy_string (GFC_INTEGER_4 destlen, char * dest,
3530                     GFC_INTEGER_4 srclen, const char * src)
3531        {
3532          if (srclen >= destlen)
3533            {
3534              // This will truncate if too long.
3535              memmove (dest, src, destlen);
3536            }
3537          else
3538            {
3539              memmove (dest, src, srclen);
3540              // Pad with spaces.
3541              memset (&dest[srclen], ' ', destlen - srclen);
3542            }
3543        }
3544
3545      We're now doing it here for better optimization, but the logic
3546      is the same.  */
3547
3548   /* For non-default character kinds, we have to multiply the string
3549      length by the base type size.  */
3550   chartype = gfc_get_char_type (dkind);
3551   slen = fold_build2 (MULT_EXPR, size_type_node,
3552                       fold_convert (size_type_node, slen),
3553                       fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
3554   dlen = fold_build2 (MULT_EXPR, size_type_node,
3555                       fold_convert (size_type_node, dlen),
3556                       fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
3557
3558   if (dlength)
3559     dest = fold_convert (pvoid_type_node, dest);
3560   else
3561     dest = gfc_build_addr_expr (pvoid_type_node, dest);
3562
3563   if (slength)
3564     src = fold_convert (pvoid_type_node, src);
3565   else
3566     src = gfc_build_addr_expr (pvoid_type_node, src);
3567
3568   /* Truncate string if source is too long.  */
3569   cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
3570   tmp2 = build_call_expr_loc (input_location,
3571                           built_in_decls[BUILT_IN_MEMMOVE],
3572                           3, dest, src, dlen);
3573
3574   /* Else copy and pad with spaces.  */
3575   tmp3 = build_call_expr_loc (input_location,
3576                           built_in_decls[BUILT_IN_MEMMOVE],
3577                           3, dest, src, slen);
3578
3579   tmp4 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest,
3580                       fold_convert (sizetype, slen));
3581   tmp4 = fill_with_spaces (tmp4, chartype,
3582                            fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
3583                                         dlen, slen));
3584
3585   gfc_init_block (&tempblock);
3586   gfc_add_expr_to_block (&tempblock, tmp3);
3587   gfc_add_expr_to_block (&tempblock, tmp4);
3588   tmp3 = gfc_finish_block (&tempblock);
3589
3590   /* The whole copy_string function is there.  */
3591   tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
3592   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3593                      build_empty_stmt (input_location));
3594   gfc_add_expr_to_block (block, tmp);
3595 }
3596
3597
3598 /* Translate a statement function.
3599    The value of a statement function reference is obtained by evaluating the
3600    expression using the values of the actual arguments for the values of the
3601    corresponding dummy arguments.  */
3602
3603 static void
3604 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
3605 {
3606   gfc_symbol *sym;
3607   gfc_symbol *fsym;
3608   gfc_formal_arglist *fargs;
3609   gfc_actual_arglist *args;
3610   gfc_se lse;
3611   gfc_se rse;
3612   gfc_saved_var *saved_vars;
3613   tree *temp_vars;
3614   tree type;
3615   tree tmp;
3616   int n;
3617
3618   sym = expr->symtree->n.sym;
3619   args = expr->value.function.actual;
3620   gfc_init_se (&lse, NULL);
3621   gfc_init_se (&rse, NULL);
3622
3623   n = 0;
3624   for (fargs = sym->formal; fargs; fargs = fargs->next)
3625     n++;
3626   saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
3627   temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
3628
3629   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3630     {
3631       /* Each dummy shall be specified, explicitly or implicitly, to be
3632          scalar.  */
3633       gcc_assert (fargs->sym->attr.dimension == 0);
3634       fsym = fargs->sym;
3635
3636       /* Create a temporary to hold the value.  */
3637       type = gfc_typenode_for_spec (&fsym->ts);
3638       temp_vars[n] = gfc_create_var (type, fsym->name);
3639
3640       if (fsym->ts.type == BT_CHARACTER)
3641         {
3642           /* Copy string arguments.  */
3643           tree arglen;
3644
3645           gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
3646                       && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
3647
3648           arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3649           tmp = gfc_build_addr_expr (build_pointer_type (type),
3650                                      temp_vars[n]);
3651
3652           gfc_conv_expr (&rse, args->expr);
3653           gfc_conv_string_parameter (&rse);
3654           gfc_add_block_to_block (&se->pre, &lse.pre);
3655           gfc_add_block_to_block (&se->pre, &rse.pre);
3656
3657           gfc_trans_string_copy (&se->pre, arglen, tmp, fsym->ts.kind,
3658                                  rse.string_length, rse.expr, fsym->ts.kind);
3659           gfc_add_block_to_block (&se->pre, &lse.post);
3660           gfc_add_block_to_block (&se->pre, &rse.post);
3661         }
3662       else
3663         {
3664           /* For everything else, just evaluate the expression.  */
3665           gfc_conv_expr (&lse, args->expr);
3666
3667           gfc_add_block_to_block (&se->pre, &lse.pre);
3668           gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
3669           gfc_add_block_to_block (&se->pre, &lse.post);
3670         }
3671
3672       args = args->next;
3673     }
3674
3675   /* Use the temporary variables in place of the real ones.  */
3676   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3677     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
3678
3679   gfc_conv_expr (se, sym->value);
3680
3681   if (sym->ts.type == BT_CHARACTER)
3682     {
3683       gfc_conv_const_charlen (sym->ts.u.cl);
3684
3685       /* Force the expression to the correct length.  */
3686       if (!INTEGER_CST_P (se->string_length)
3687           || tree_int_cst_lt (se->string_length,
3688                               sym->ts.u.cl->backend_decl))
3689         {
3690           type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
3691           tmp = gfc_create_var (type, sym->name);
3692           tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
3693           gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
3694                                  sym->ts.kind, se->string_length, se->expr,
3695                                  sym->ts.kind);
3696           se->expr = tmp;
3697         }
3698       se->string_length = sym->ts.u.cl->backend_decl;
3699     }
3700
3701   /* Restore the original variables.  */
3702   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3703     gfc_restore_sym (fargs->sym, &saved_vars[n]);
3704   gfc_free (saved_vars);
3705 }
3706
3707
3708 /* Translate a function expression.  */
3709
3710 static void
3711 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
3712 {
3713   gfc_symbol *sym;
3714
3715   if (expr->value.function.isym)
3716     {
3717       gfc_conv_intrinsic_function (se, expr);
3718       return;
3719     }
3720
3721   /* We distinguish statement functions from general functions to improve
3722      runtime performance.  */
3723   if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
3724     {
3725       gfc_conv_statement_function (se, expr);
3726       return;
3727     }
3728
3729   /* expr.value.function.esym is the resolved (specific) function symbol for
3730      most functions.  However this isn't set for dummy procedures.  */
3731   sym = expr->value.function.esym;
3732   if (!sym)
3733     sym = expr->symtree->n.sym;
3734
3735   gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
3736                           NULL_TREE);
3737 }
3738
3739
3740 static void
3741 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
3742 {
3743   gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
3744   gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
3745
3746   gfc_conv_tmp_array_ref (se);
3747   gfc_advance_se_ss_chain (se);
3748 }
3749
3750
3751 /* Build a static initializer.  EXPR is the expression for the initial value.
3752    The other parameters describe the variable of the component being 
3753    initialized. EXPR may be null.  */
3754
3755 tree
3756 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
3757                       bool array, bool pointer)
3758 {
3759   gfc_se se;
3760
3761   if (!(expr || pointer))
3762     return NULL_TREE;
3763
3764   /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
3765      (these are the only two iso_c_binding derived types that can be
3766      used as initialization expressions).  If so, we need to modify
3767      the 'expr' to be that for a (void *).  */
3768   if (expr != NULL && expr->ts.type == BT_DERIVED
3769       && expr->ts.is_iso_c && expr->ts.u.derived)
3770     {
3771       gfc_symbol *derived = expr->ts.u.derived;
3772
3773       expr = gfc_int_expr (0);
3774
3775       /* The derived symbol has already been converted to a (void *).  Use
3776          its kind.  */
3777       expr->ts.f90_type = derived->ts.f90_type;
3778       expr->ts.kind = derived->ts.kind;
3779     }
3780   
3781   if (array)
3782     {
3783       /* Arrays need special handling.  */
3784       if (pointer)
3785         return gfc_build_null_descriptor (type);
3786       else
3787         return gfc_conv_array_initializer (type, expr);
3788     }
3789   else if (pointer)
3790     return fold_convert (type, null_pointer_node);
3791   else
3792     {
3793       switch (ts->type)
3794         {
3795         case BT_DERIVED:
3796         case BT_CLASS:
3797           gfc_init_se (&se, NULL);
3798           gfc_conv_structure (&se, expr, 1);
3799           return se.expr;
3800
3801         case BT_CHARACTER:
3802           return gfc_conv_string_init (ts->u.cl->backend_decl,expr);
3803
3804         default:
3805           gfc_init_se (&se, NULL);
3806           gfc_conv_constant (&se, expr);
3807           return se.expr;
3808         }
3809     }
3810 }
3811   
3812 static tree
3813 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3814 {
3815   gfc_se rse;
3816   gfc_se lse;
3817   gfc_ss *rss;
3818   gfc_ss *lss;
3819   stmtblock_t body;
3820   stmtblock_t block;
3821   gfc_loopinfo loop;
3822   int n;
3823   tree tmp;
3824
3825   gfc_start_block (&block);
3826
3827   /* Initialize the scalarizer.  */
3828   gfc_init_loopinfo (&loop);
3829
3830   gfc_init_se (&lse, NULL);
3831   gfc_init_se (&rse, NULL);
3832
3833   /* Walk the rhs.  */
3834   rss = gfc_walk_expr (expr);
3835   if (rss == gfc_ss_terminator)
3836     {
3837       /* The rhs is scalar.  Add a ss for the expression.  */
3838       rss = gfc_get_ss ();
3839       rss->next = gfc_ss_terminator;
3840       rss->type = GFC_SS_SCALAR;
3841       rss->expr = expr;
3842     }
3843
3844   /* Create a SS for the destination.  */
3845   lss = gfc_get_ss ();
3846   lss->type = GFC_SS_COMPONENT;
3847   lss->expr = NULL;
3848   lss->shape = gfc_get_shape (cm->as->rank);
3849   lss->next = gfc_ss_terminator;
3850   lss->data.info.dimen = cm->as->rank;
3851   lss->data.info.descriptor = dest;
3852   lss->data.info.data = gfc_conv_array_data (dest);
3853   lss->data.info.offset = gfc_conv_array_offset (dest);
3854   for (n = 0; n < cm->as->rank; n++)
3855     {
3856       lss->data.info.dim[n] = n;
3857       lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
3858       lss->data.info.stride[n] = gfc_index_one_node;
3859
3860       mpz_init (lss->shape[n]);
3861       mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
3862                cm->as->lower[n]->value.integer);
3863       mpz_add_ui (lss->shape[n], lss->shape[n], 1);
3864     }
3865   
3866   /* Associate the SS with the loop.  */
3867   gfc_add_ss_to_loop (&loop, lss);
3868   gfc_add_ss_to_loop (&loop, rss);
3869
3870   /* Calculate the bounds of the scalarization.  */
3871   gfc_conv_ss_startstride (&loop);
3872
3873   /* Setup the scalarizing loops.  */
3874   gfc_conv_loop_setup (&loop, &expr->where);
3875
3876   /* Setup the gfc_se structures.  */
3877   gfc_copy_loopinfo_to_se (&lse, &loop);
3878   gfc_copy_loopinfo_to_se (&rse, &loop);
3879
3880   rse.ss = rss;
3881   gfc_mark_ss_chain_used (rss, 1);
3882   lse.ss = lss;
3883   gfc_mark_ss_chain_used (lss, 1);
3884
3885   /* Start the scalarized loop body.  */
3886   gfc_start_scalarized_body (&loop, &body);
3887
3888   gfc_conv_tmp_array_ref (&lse);
3889   if (cm->ts.type == BT_CHARACTER)
3890     lse.string_length = cm->ts.u.cl->backend_decl;
3891
3892   gfc_conv_expr (&rse, expr);
3893
3894   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
3895   gfc_add_expr_to_block (&body, tmp);
3896
3897   gcc_assert (rse.ss == gfc_ss_terminator);
3898
3899   /* Generate the copying loops.  */
3900   gfc_trans_scalarizing_loops (&loop, &body);
3901
3902   /* Wrap the whole thing up.  */
3903   gfc_add_block_to_block (&block, &loop.pre);
3904   gfc_add_block_to_block (&block, &loop.post);
3905
3906   for (n = 0; n < cm->as->rank; n++)
3907     mpz_clear (lss->shape[n]);
3908   gfc_free (lss->shape);
3909
3910   gfc_cleanup_loop (&loop);
3911
3912   return gfc_finish_block (&block);
3913 }
3914
3915
3916 /* Assign a single component of a derived type constructor.  */
3917
3918 static tree
3919 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3920 {
3921   gfc_se se;
3922   gfc_se lse;
3923   gfc_ss *rss;
3924   stmtblock_t block;
3925   tree tmp;
3926   tree offset;
3927   int n;
3928
3929   gfc_start_block (&block);
3930
3931   if (cm->attr.pointer)
3932     {
3933       gfc_init_se (&se, NULL);
3934       /* Pointer component.  */
3935       if (cm->attr.dimension)
3936         {
3937           /* Array pointer.  */
3938           if (expr->expr_type == EXPR_NULL)
3939             gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
3940           else
3941             {
3942               rss = gfc_walk_expr (expr);
3943               se.direct_byref = 1;
3944               se.expr = dest;
3945               gfc_conv_expr_descriptor (&se, expr, rss);
3946               gfc_add_block_to_block (&block, &se.pre);
3947               gfc_add_block_to_block (&block, &se.post);
3948             }
3949         }
3950       else
3951         {
3952           /* Scalar pointers.  */
3953           se.want_pointer = 1;
3954           gfc_conv_expr (&se, expr);
3955           gfc_add_block_to_block (&block, &se.pre);
3956           gfc_add_modify (&block, dest,
3957                                fold_convert (TREE_TYPE (dest), se.expr));
3958           gfc_add_block_to_block (&block, &se.post);
3959         }
3960     }
3961   else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
3962     {
3963       /* NULL initialization for CLASS components.  */
3964       tmp = gfc_trans_structure_assign (dest,
3965                                         gfc_default_initializer (&cm->ts));
3966       gfc_add_expr_to_block (&block, tmp);
3967     }
3968   else if (cm->attr.dimension)
3969     {
3970       if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
3971         gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
3972       else if (cm->attr.allocatable)
3973         {
3974           tree tmp2;
3975
3976           gfc_init_se (&se, NULL);
3977  
3978           rss = gfc_walk_expr (expr);
3979           se.want_pointer = 0;
3980           gfc_conv_expr_descriptor (&se, expr, rss);
3981           gfc_add_block_to_block (&block, &se.pre);
3982           gfc_add_modify (&block, dest, se.expr);
3983
3984           if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
3985             tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr, dest,
3986                                        cm->as->rank);
3987           else
3988             tmp = gfc_duplicate_allocatable (dest, se.expr,
3989                                              TREE_TYPE(cm->backend_decl),
3990                                              cm->as->rank);
3991
3992           gfc_add_expr_to_block (&block, tmp);
3993           gfc_add_block_to_block (&block, &se.post);
3994
3995           if (expr->expr_type != EXPR_VARIABLE)
3996             gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
3997
3998           /* Shift the lbound and ubound of temporaries to being unity, rather
3999              than zero, based.  Calculate the offset for all cases.  */
4000           offset = gfc_conv_descriptor_offset_get (dest);
4001           gfc_add_modify (&block, offset, gfc_index_zero_node);
4002           tmp2 =gfc_create_var (gfc_array_index_type, NULL);
4003           for (n = 0; n < expr->rank; n++)
4004             {
4005               if (expr->expr_type != EXPR_VARIABLE
4006                     && expr->expr_type != EXPR_CONSTANT)
4007                 {
4008                   tree span;
4009                   tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
4010                   span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
4011                             gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
4012                   tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4013                                      span, gfc_index_one_node);
4014                   gfc_conv_descriptor_ubound_set (&block, dest, gfc_rank_cst[n],
4015                                                   tmp);
4016                   gfc_conv_descriptor_lbound_set (&block, dest, gfc_rank_cst[n],
4017                                                   gfc_index_one_node);
4018                 }
4019               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4020                                  gfc_conv_descriptor_lbound_get (dest,
4021                                                              gfc_rank_cst[n]),
4022                                  gfc_conv_descriptor_stride_get (dest,
4023                                                              gfc_rank_cst[n]));
4024               gfc_add_modify (&block, tmp2, tmp);
4025               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
4026               gfc_conv_descriptor_offset_set (&block, dest, tmp);
4027             }
4028
4029           if (expr->expr_type == EXPR_FUNCTION
4030                 && expr->value.function.isym
4031                 && expr->value.function.isym->conversion
4032                 && expr->value.function.actual->expr
4033                 && expr->value.function.actual->expr->expr_type
4034                                                 == EXPR_VARIABLE)
4035             {
4036               /* If a conversion expression has a null data pointer
4037                  argument, nullify the allocatable component.  */
4038               gfc_symbol *s;
4039               tree non_null_expr;
4040               tree null_expr;
4041               s = expr->value.function.actual->expr->symtree->n.sym;
4042               if (s->attr.allocatable || s->attr.pointer)
4043                 {
4044                   non_null_expr = gfc_finish_block (&block);
4045                   gfc_start_block (&block);
4046                   gfc_conv_descriptor_data_set (&block, dest,
4047                                                 null_pointer_node);
4048                   null_expr = gfc_finish_block (&block);
4049                   tmp = gfc_conv_descriptor_data_get (s->backend_decl);
4050                   tmp = build2 (EQ_EXPR, boolean_type_node, tmp,
4051                                 fold_convert (TREE_TYPE (tmp),
4052                                               null_pointer_node));
4053                   return build3_v (COND_EXPR, tmp, null_expr,
4054                                    non_null_expr);
4055                 }
4056             }
4057         }
4058       else
4059         {
4060           tmp = gfc_trans_subarray_assign (dest, cm, expr);
4061           gfc_add_expr_to_block (&block, tmp);
4062         }
4063     }
4064   else if (expr->ts.type == BT_DERIVED)
4065     {
4066       if (expr->expr_type != EXPR_STRUCTURE)
4067         {
4068           gfc_init_se (&se, NULL);
4069           gfc_conv_expr (&se, expr);
4070           gfc_add_block_to_block (&block, &se.pre);
4071           gfc_add_modify (&block, dest,
4072                                fold_convert (TREE_TYPE (dest), se.expr));
4073           gfc_add_block_to_block (&block, &se.post);
4074         }
4075       else
4076         {
4077           /* Nested constructors.  */
4078           tmp = gfc_trans_structure_assign (dest, expr);
4079           gfc_add_expr_to_block (&block, tmp);
4080         }
4081     }
4082   else
4083     {
4084       /* Scalar component.  */
4085       gfc_init_se (&se, NULL);
4086       gfc_init_se (&lse, NULL);
4087
4088       gfc_conv_expr (&se, expr);
4089       if (cm->ts.type == BT_CHARACTER)
4090         lse.string_length = cm->ts.u.cl->backend_decl;
4091       lse.expr = dest;
4092       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
4093       gfc_add_expr_to_block (&block, tmp);
4094     }
4095   return gfc_finish_block (&block);
4096 }
4097
4098 /* Assign a derived type constructor to a variable.  */
4099
4100 static tree
4101 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
4102 {
4103   gfc_constructor *c;
4104   gfc_component *cm;
4105   stmtblock_t block;
4106   tree field;
4107   tree tmp;
4108
4109   gfc_start_block (&block);
4110   cm = expr->ts.u.derived->components;
4111   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
4112     {
4113       /* Skip absent members in default initializers.  */
4114       if (!c->expr)
4115         continue;
4116
4117       field = cm->backend_decl;
4118       tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field),
4119                          dest, field, NULL_TREE);
4120       tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
4121       gfc_add_expr_to_block (&block, tmp);
4122     }
4123   return gfc_finish_block (&block);
4124 }
4125
4126 /* Build an expression for a constructor. If init is nonzero then
4127    this is part of a static variable initializer.  */
4128
4129 void
4130 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
4131 {
4132   gfc_constructor *c;
4133   gfc_component *cm;
4134   tree val;
4135   tree type;
4136   tree tmp;
4137   VEC(constructor_elt,gc) *v = NULL;
4138
4139   gcc_assert (se->ss == NULL);
4140   gcc_assert (expr->expr_type == EXPR_STRUCTURE);
4141   type = gfc_typenode_for_spec (&expr->ts);
4142
4143   if (!init)
4144     {
4145       /* Create a temporary variable and fill it in.  */
4146       se->expr = gfc_create_var (type, expr->ts.u.derived->name);
4147       tmp = gfc_trans_structure_assign (se->expr, expr);
4148       gfc_add_expr_to_block (&se->pre, tmp);
4149       return;
4150     }
4151
4152   cm = expr->ts.u.derived->components;
4153
4154   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
4155     {
4156       /* Skip absent members in default initializers and allocatable
4157          components.  Although the latter have a default initializer
4158          of EXPR_NULL,... by default, the static nullify is not needed
4159          since this is done every time we come into scope.  */
4160       if (!c->expr || cm->attr.allocatable)
4161         continue;
4162
4163       if (cm->ts.type == BT_CLASS)
4164         {
4165           val = gfc_conv_initializer (c->expr, &cm->ts,
4166               TREE_TYPE (cm->ts.u.derived->components->backend_decl),
4167               cm->ts.u.derived->components->attr.dimension,
4168               cm->ts.u.derived->components->attr.pointer);
4169
4170           /* Append it to the constructor list.  */
4171           CONSTRUCTOR_APPEND_ELT (v, cm->ts.u.derived->components->backend_decl,
4172                                   val);
4173         }
4174       else
4175         {
4176           val = gfc_conv_initializer (c->expr, &cm->ts,
4177               TREE_TYPE (cm->backend_decl), cm->attr.dimension,
4178               cm->attr.pointer || cm->attr.proc_pointer);
4179
4180           /* Append it to the constructor list.  */
4181           CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
4182         }
4183     }
4184   se->expr = build_constructor (type, v);
4185   if (init) 
4186     TREE_CONSTANT (se->expr) = 1;
4187 }
4188
4189
4190 /* Translate a substring expression.  */
4191
4192 static void
4193 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
4194 {
4195   gfc_ref *ref;
4196
4197   ref = expr->ref;
4198
4199   gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
4200
4201   se->expr = gfc_build_wide_string_const (expr->ts.kind,
4202                                           expr->value.character.length,
4203                                           expr->value.character.string);
4204
4205   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
4206   TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
4207
4208   if (ref)
4209     gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
4210 }
4211
4212
4213 /* Entry point for expression translation.  Evaluates a scalar quantity.
4214    EXPR is the expression to be translated, and SE is the state structure if
4215    called from within the scalarized.  */
4216
4217 void
4218 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
4219 {
4220   if (se->ss && se->ss->expr == expr
4221       && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
4222     {
4223       /* Substitute a scalar expression evaluated outside the scalarization
4224          loop.  */
4225       se->expr = se->ss->data.scalar.expr;
4226       se->string_length = se->ss->string_length;
4227       gfc_advance_se_ss_chain (se);
4228       return;
4229     }
4230
4231   /* We need to convert the expressions for the iso_c_binding derived types.
4232      C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
4233      null_pointer_node.  C_PTR and C_FUNPTR are converted to match the
4234      typespec for the C_PTR and C_FUNPTR symbols, which has already been
4235      updated to be an integer with a kind equal to the size of a (void *).  */
4236   if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
4237       && expr->ts.u.derived->attr.is_iso_c)
4238     {
4239       if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
4240           || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
4241         {
4242           /* Set expr_type to EXPR_NULL, which will result in
4243              null_pointer_node being used below.  */
4244           expr->expr_type = EXPR_NULL;
4245         }
4246       else
4247         {
4248           /* Update the type/kind of the expression to be what the new
4249              type/kind are for the updated symbols of C_PTR/C_FUNPTR.  */
4250           expr->ts.type = expr->ts.u.derived->ts.type;
4251           expr->ts.f90_type = expr->ts.u.derived->ts.f90_type;
4252           expr->ts.kind = expr->ts.u.derived->ts.kind;
4253         }
4254     }
4255   
4256   switch (expr->expr_type)
4257     {
4258     case EXPR_OP:
4259       gfc_conv_expr_op (se, expr);
4260       break;
4261
4262     case EXPR_FUNCTION:
4263       gfc_conv_function_expr (se, expr);
4264       break;
4265
4266     case EXPR_CONSTANT:
4267       gfc_conv_constant (se, expr);
4268       break;
4269
4270     case EXPR_VARIABLE:
4271       gfc_conv_variable (se, expr);
4272       break;
4273
4274     case EXPR_NULL:
4275       se->expr = null_pointer_node;
4276       break;
4277
4278     case EXPR_SUBSTRING:
4279       gfc_conv_substring_expr (se, expr);
4280       break;
4281
4282     case EXPR_STRUCTURE:
4283       gfc_conv_structure (se, expr, 0);
4284       break;
4285
4286     case EXPR_ARRAY:
4287       gfc_conv_array_constructor_expr (se, expr);
4288       break;
4289
4290     default:
4291       gcc_unreachable ();
4292       break;
4293     }
4294 }
4295
4296 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
4297    of an assignment.  */
4298 void
4299 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
4300 {
4301   gfc_conv_expr (se, expr);
4302   /* All numeric lvalues should have empty post chains.  If not we need to
4303      figure out a way of rewriting an lvalue so that it has no post chain.  */
4304   gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
4305 }
4306
4307 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
4308    numeric expressions.  Used for scalar values where inserting cleanup code
4309    is inconvenient.  */
4310 void
4311 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
4312 {
4313   tree val;
4314
4315   gcc_assert (expr->ts.type != BT_CHARACTER);
4316   gfc_conv_expr (se, expr);
4317   if (se->post.head)
4318     {
4319       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
4320       gfc_add_modify (&se->pre, val, se->expr);
4321       se->expr = val;
4322       gfc_add_block_to_block (&se->pre, &se->post);
4323     }
4324 }
4325
4326 /* Helper to translate an expression and convert it to a particular type.  */
4327 void
4328 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
4329 {
4330   gfc_conv_expr_val (se, expr);
4331   se->expr = convert (type, se->expr);
4332 }
4333
4334
4335 /* Converts an expression so that it can be passed by reference.  Scalar
4336    values only.  */
4337
4338 void
4339 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
4340 {
4341   tree var;
4342
4343   if (se->ss && se->ss->expr == expr
4344       && se->ss->type == GFC_SS_REFERENCE)
4345     {
4346       se->expr = se->ss->data.scalar.expr;
4347       se->string_length = se->ss->string_length;
4348       gfc_advance_se_ss_chain (se);
4349       return;
4350     }
4351
4352   if (expr->ts.type == BT_CHARACTER)
4353     {
4354       gfc_conv_expr (se, expr);
4355       gfc_conv_string_parameter (se);
4356       return;
4357     }
4358
4359   if (expr->expr_type == EXPR_VARIABLE)
4360     {
4361       se->want_pointer = 1;
4362       gfc_conv_expr (se, expr);
4363       if (se->post.head)
4364         {
4365           var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4366           gfc_add_modify (&se->pre, var, se->expr);
4367           gfc_add_block_to_block (&se->pre, &se->post);
4368           se->expr = var;
4369         }
4370       return;
4371     }
4372
4373   if (expr->expr_type == EXPR_FUNCTION
4374       && ((expr->value.function.esym
4375            && expr->value.function.esym->result->attr.pointer
4376            && !expr->value.function.esym->result->attr.dimension)
4377           || (!expr->value.function.esym
4378               && expr->symtree->n.sym->attr.pointer
4379               && !expr->symtree->n.sym->attr.dimension)))
4380     {
4381       se->want_pointer = 1;
4382       gfc_conv_expr (se, expr);
4383       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4384       gfc_add_modify (&se->pre, var, se->expr);
4385       se->expr = var;
4386       return;
4387     }
4388
4389
4390   gfc_conv_expr (se, expr);
4391
4392   /* Create a temporary var to hold the value.  */
4393   if (TREE_CONSTANT (se->expr))
4394     {
4395       tree tmp = se->expr;
4396       STRIP_TYPE_NOPS (tmp);
4397       var = build_decl (input_location,
4398                         CONST_DECL, NULL, TREE_TYPE (tmp));
4399       DECL_INITIAL (var) = tmp;
4400       TREE_STATIC (var) = 1;
4401       pushdecl (var);
4402     }
4403   else
4404     {
4405       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4406       gfc_add_modify (&se->pre, var, se->expr);
4407     }
4408   gfc_add_block_to_block (&se->pre, &se->post);
4409
4410   /* Take the address of that value.  */
4411   se->expr = gfc_build_addr_expr (NULL_TREE, var);
4412 }
4413
4414
4415 tree
4416 gfc_trans_pointer_assign (gfc_code * code)
4417 {
4418   return gfc_trans_pointer_assignment (code->expr1, code->expr2);
4419 }
4420
4421
4422 /* Generate code for a pointer assignment.  */
4423
4424 tree
4425 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
4426 {
4427   gfc_se lse;
4428   gfc_se rse;
4429   gfc_ss *lss;
4430   gfc_ss *rss;
4431   stmtblock_t block;
4432   tree desc;
4433   tree tmp;
4434   tree decl;
4435
4436   gfc_start_block (&block);
4437
4438   gfc_init_se (&lse, NULL);
4439
4440   lss = gfc_walk_expr (expr1);
4441   rss = gfc_walk_expr (expr2);
4442   if (lss == gfc_ss_terminator)
4443     {
4444       /* Scalar pointers.  */
4445       lse.want_pointer = 1;
4446       gfc_conv_expr (&lse, expr1);
4447       gcc_assert (rss == gfc_ss_terminator);
4448       gfc_init_se (&rse, NULL);
4449       rse.want_pointer = 1;
4450       gfc_conv_expr (&rse, expr2);
4451
4452       if (expr1->symtree->n.sym->attr.proc_pointer
4453           && expr1->symtree->n.sym->attr.dummy)
4454         lse.expr = build_fold_indirect_ref_loc (input_location,
4455                                             lse.expr);
4456
4457       if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
4458           && expr2->symtree->n.sym->attr.dummy)
4459         rse.expr = build_fold_indirect_ref_loc (input_location,
4460                                             rse.expr);
4461
4462       gfc_add_block_to_block (&block, &lse.pre);
4463       gfc_add_block_to_block (&block, &rse.pre);
4464
4465       /* Check character lengths if character expression.  The test is only
4466          really added if -fbounds-check is enabled.  */
4467       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
4468           && !expr1->symtree->n.sym->attr.proc_pointer
4469           && !gfc_is_proc_ptr_comp (expr1, NULL))
4470         {
4471           gcc_assert (expr2->ts.type == BT_CHARACTER);
4472           gcc_assert (lse.string_length && rse.string_length);
4473           gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4474                                        lse.string_length, rse.string_length,
4475                                        &block);
4476         }
4477
4478       gfc_add_modify (&block, lse.expr,
4479                            fold_convert (TREE_TYPE (lse.expr), rse.expr));
4480
4481       gfc_add_block_to_block (&block, &rse.post);
4482       gfc_add_block_to_block (&block, &lse.post);
4483     }
4484   else
4485     {
4486       tree strlen_lhs;
4487       tree strlen_rhs = NULL_TREE;
4488
4489       /* Array pointer.  */
4490       gfc_conv_expr_descriptor (&lse, expr1, lss);
4491       strlen_lhs = lse.string_length;
4492       switch (expr2->expr_type)
4493         {
4494         case EXPR_NULL:
4495           /* Just set the data pointer to null.  */
4496           gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
4497           break;
4498
4499         case EXPR_VARIABLE:
4500           /* Assign directly to the pointer's descriptor.  */
4501           lse.direct_byref = 1;
4502           gfc_conv_expr_descriptor (&lse, expr2, rss);
4503           strlen_rhs = lse.string_length;
4504
4505           /* If this is a subreference array pointer assignment, use the rhs
4506              descriptor element size for the lhs span.  */
4507           if (expr1->symtree->n.sym->attr.subref_array_pointer)
4508             {
4509               decl = expr1->symtree->n.sym->backend_decl;
4510               gfc_init_se (&rse, NULL);
4511               rse.descriptor_only = 1;
4512               gfc_conv_expr (&rse, expr2);
4513               tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
4514               tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
4515               if (!INTEGER_CST_P (tmp))
4516                 gfc_add_block_to_block (&lse.post, &rse.pre);
4517               gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
4518             }
4519
4520           break;
4521
4522         default:
4523           /* Assign to a temporary descriptor and then copy that
4524              temporary to the pointer.  */
4525           desc = lse.expr;
4526           tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
4527
4528           lse.expr = tmp;
4529           lse.direct_byref = 1;
4530           gfc_conv_expr_descriptor (&lse, expr2, rss);
4531           strlen_rhs = lse.string_length;
4532           gfc_add_modify (&lse.pre, desc, tmp);
4533           break;
4534         }
4535
4536       gfc_add_block_to_block (&block, &lse.pre);
4537
4538       /* Check string lengths if applicable.  The check is only really added
4539          to the output code if -fbounds-check is enabled.  */
4540       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
4541         {
4542           gcc_assert (expr2->ts.type == BT_CHARACTER);
4543           gcc_assert (strlen_lhs && strlen_rhs);
4544           gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4545                                        strlen_lhs, strlen_rhs, &block);
4546         }
4547
4548       gfc_add_block_to_block (&block, &lse.post);
4549     }
4550   return gfc_finish_block (&block);
4551 }
4552
4553
4554 /* Makes sure se is suitable for passing as a function string parameter.  */
4555 /* TODO: Need to check all callers of this function.  It may be abused.  */
4556
4557 void
4558 gfc_conv_string_parameter (gfc_se * se)
4559 {
4560   tree type;
4561
4562   if (TREE_CODE (se->expr) == STRING_CST)
4563     {
4564       type = TREE_TYPE (TREE_TYPE (se->expr));
4565       se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4566       return;
4567     }
4568
4569   if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
4570     {
4571       if (TREE_CODE (se->expr) != INDIRECT_REF)
4572         {
4573           type = TREE_TYPE (se->expr);
4574           se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4575         }
4576       else
4577         {
4578           type = gfc_get_character_type_len (gfc_default_character_kind,
4579                                              se->string_length);
4580           type = build_pointer_type (type);
4581           se->expr = gfc_build_addr_expr (type, se->expr);
4582         }
4583     }
4584
4585   gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
4586   gcc_assert (se->string_length
4587           && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
4588 }
4589
4590
4591 /* Generate code for assignment of scalar variables.  Includes character
4592    strings and derived types with allocatable components.  */
4593
4594 tree
4595 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
4596                          bool l_is_temp, bool r_is_var)
4597 {
4598   stmtblock_t block;
4599   tree tmp;
4600   tree cond;
4601
4602   gfc_init_block (&block);
4603
4604   if (ts.type == BT_CHARACTER)
4605     {
4606       tree rlen = NULL;
4607       tree llen = NULL;
4608
4609       if (lse->string_length != NULL_TREE)
4610         {
4611           gfc_conv_string_parameter (lse);
4612           gfc_add_block_to_block (&block, &lse->pre);
4613           llen = lse->string_length;
4614         }
4615
4616       if (rse->string_length != NULL_TREE)
4617         {
4618           gcc_assert (rse->string_length != NULL_TREE);
4619           gfc_conv_string_parameter (rse);
4620           gfc_add_block_to_block (&block, &rse->pre);
4621           rlen = rse->string_length;
4622         }
4623
4624       gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
4625                              rse->expr, ts.kind);
4626     }
4627   else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
4628     {
4629       cond = NULL_TREE;
4630         
4631       /* Are the rhs and the lhs the same?  */
4632       if (r_is_var)
4633         {
4634           cond = fold_build2 (EQ_EXPR, boolean_type_node,
4635                               gfc_build_addr_expr (NULL_TREE, lse->expr),
4636                               gfc_build_addr_expr (NULL_TREE, rse->expr));
4637           cond = gfc_evaluate_now (cond, &lse->pre);
4638         }
4639
4640       /* Deallocate the lhs allocated components as long as it is not
4641          the same as the rhs.  This must be done following the assignment
4642          to prevent deallocating data that could be used in the rhs
4643          expression.  */
4644       if (!l_is_temp)
4645         {
4646           tmp = gfc_evaluate_now (lse->expr, &lse->pre);
4647           tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
4648           if (r_is_var)
4649             tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4650                             tmp);
4651           gfc_add_expr_to_block (&lse->post, tmp);
4652         }
4653
4654       gfc_add_block_to_block (&block, &rse->pre);
4655       gfc_add_block_to_block (&block, &lse->pre);
4656
4657       gfc_add_modify (&block, lse->expr,
4658                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
4659
4660       /* Do a deep copy if the rhs is a variable, if it is not the
4661          same as the lhs.  */
4662       if (r_is_var)
4663         {
4664           tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
4665           tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4666                           tmp);
4667           gfc_add_expr_to_block (&block, tmp);
4668         }
4669     }
4670   else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
4671     {
4672       gfc_add_block_to_block (&block, &lse->pre);
4673       gfc_add_block_to_block (&block, &rse->pre);
4674       tmp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lse->expr), rse->expr);
4675       gfc_add_modify (&block, lse->expr, tmp);
4676     }
4677   else
4678     {
4679       gfc_add_block_to_block (&block, &lse->pre);
4680       gfc_add_block_to_block (&block, &rse->pre);
4681
4682       gfc_add_modify (&block, lse->expr,
4683                       fold_convert (TREE_TYPE (lse->expr), rse->expr));
4684     }
4685
4686   gfc_add_block_to_block (&block, &lse->post);
4687   gfc_add_block_to_block (&block, &rse->post);
4688
4689   return gfc_finish_block (&block);
4690 }
4691
4692
4693 /* Try to translate array(:) = func (...), where func is a transformational
4694    array function, without using a temporary.  Returns NULL is this isn't the
4695    case.  */
4696
4697 static tree
4698 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
4699 {
4700   gfc_se se;
4701   gfc_ss *ss;
4702   gfc_ref * ref;
4703   bool seen_array_ref;
4704   bool c = false;
4705   gfc_component *comp = NULL;
4706
4707   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
4708   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
4709     return NULL;
4710
4711   /* Elemental functions don't need a temporary anyway.  */
4712   if (expr2->value.function.esym != NULL
4713       && expr2->value.function.esym->attr.elemental)
4714     return NULL;
4715
4716   /* Fail if rhs is not FULL or a contiguous section.  */
4717   if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
4718     return NULL;
4719
4720   /* Fail if EXPR1 can't be expressed as a descriptor.  */
4721   if (gfc_ref_needs_temporary_p (expr1->ref))
4722     return NULL;
4723
4724   /* Functions returning pointers need temporaries.  */
4725   if (expr2->symtree->n.sym->attr.pointer 
4726       || expr2->symtree->n.sym->attr.allocatable)
4727     return NULL;
4728
4729   /* Character array functions need temporaries unless the
4730      character lengths are the same.  */
4731   if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
4732     {
4733       if (expr1->ts.u.cl->length == NULL
4734             || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
4735         return NULL;
4736
4737       if (expr2->ts.u.cl->length == NULL
4738             || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
4739         return NULL;
4740
4741       if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
4742                      expr2->ts.u.cl->length->value.integer) != 0)
4743         return NULL;
4744     }
4745
4746   /* Check that no LHS component references appear during an array
4747      reference. This is needed because we do not have the means to
4748      span any arbitrary stride with an array descriptor. This check
4749      is not needed for the rhs because the function result has to be
4750      a complete type.  */
4751   seen_array_ref = false;
4752   for (ref = expr1->ref; ref; ref = ref->next)
4753     {
4754       if (ref->type == REF_ARRAY)
4755         seen_array_ref= true;
4756       else if (ref->type == REF_COMPONENT && seen_array_ref)
4757         return NULL;
4758     }
4759
4760   /* Check for a dependency.  */
4761   if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
4762                                    expr2->value.function.esym,
4763                                    expr2->value.function.actual,
4764                                    NOT_ELEMENTAL))
4765     return NULL;
4766
4767   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
4768      functions.  */
4769   gcc_assert (expr2->value.function.isym
4770               || (gfc_is_proc_ptr_comp (expr2, &comp)
4771                   && comp && comp->attr.dimension)
4772               || (!comp && gfc_return_by_reference (expr2->value.function.esym)
4773                   && expr2->value.function.esym->result->attr.dimension));
4774
4775   ss = gfc_walk_expr (expr1);
4776   gcc_assert (ss != gfc_ss_terminator);
4777   gfc_init_se (&se, NULL);
4778   gfc_start_block (&se.pre);
4779   se.want_pointer = 1;
4780
4781   gfc_conv_array_parameter (&se, expr1, ss, 0, NULL, NULL, NULL);
4782
4783   se.direct_byref = 1;
4784   se.ss = gfc_walk_expr (expr2);
4785   gcc_assert (se.ss != gfc_ss_terminator);
4786   gfc_conv_function_expr (&se, expr2);
4787   gfc_add_block_to_block (&se.pre, &se.post);
4788
4789   return gfc_finish_block (&se.pre);
4790 }
4791
4792 /* Determine whether the given EXPR_CONSTANT is a zero initializer.  */
4793
4794 static bool
4795 is_zero_initializer_p (gfc_expr * expr)
4796 {
4797   if (expr->expr_type != EXPR_CONSTANT)
4798     return false;
4799
4800   /* We ignore constants with prescribed memory representations for now.  */
4801   if (expr->representation.string)
4802     return false;
4803
4804   switch (expr->ts.type)
4805     {
4806     case BT_INTEGER:
4807       return mpz_cmp_si (expr->value.integer, 0) == 0;
4808
4809     case BT_REAL:
4810       return mpfr_zero_p (expr->value.real)
4811              && MPFR_SIGN (expr->value.real) >= 0;
4812
4813     case BT_LOGICAL:
4814       return expr->value.logical == 0;
4815
4816     case BT_COMPLEX:
4817       return mpfr_zero_p (mpc_realref (expr->value.complex))
4818              && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
4819              && mpfr_zero_p (mpc_imagref (expr->value.complex))
4820              && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
4821
4822     default:
4823       break;
4824     }
4825   return false;
4826 }
4827
4828 /* Try to efficiently translate array(:) = 0.  Return NULL if this
4829    can't be done.  */
4830
4831 static tree
4832 gfc_trans_zero_assign (gfc_expr * expr)
4833 {
4834   tree dest, len, type;
4835   tree tmp;
4836   gfc_symbol *sym;
4837
4838   sym = expr->symtree->n.sym;
4839   dest = gfc_get_symbol_decl (sym);
4840
4841   type = TREE_TYPE (dest);
4842   if (POINTER_TYPE_P (type))
4843     type = TREE_TYPE (type);
4844   if (!GFC_ARRAY_TYPE_P (type))
4845     return NULL_TREE;
4846
4847   /* Determine the length of the array.  */
4848   len = GFC_TYPE_ARRAY_SIZE (type);
4849   if (!len || TREE_CODE (len) != INTEGER_CST)
4850     return NULL_TREE;
4851
4852   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
4853   len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
4854                      fold_convert (gfc_array_index_type, tmp));
4855
4856   /* If we are zeroing a local array avoid taking its address by emitting
4857      a = {} instead.  */
4858   if (!POINTER_TYPE_P (TREE_TYPE (dest)))
4859     return build2 (MODIFY_EXPR, void_type_node,
4860                    dest, build_constructor (TREE_TYPE (dest), NULL));
4861
4862   /* Convert arguments to the correct types.  */
4863   dest = fold_convert (pvoid_type_node, dest);
4864   len = fold_convert (size_type_node, len);
4865
4866   /* Construct call to __builtin_memset.  */
4867   tmp = build_call_expr_loc (input_location,
4868                          built_in_decls[BUILT_IN_MEMSET],
4869                          3, dest, integer_zero_node, len);
4870   return fold_convert (void_type_node, tmp);
4871 }
4872
4873
4874 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
4875    that constructs the call to __builtin_memcpy.  */
4876
4877 tree
4878 gfc_build_memcpy_call (tree dst, tree src, tree len)
4879 {
4880   tree tmp;
4881
4882   /* Convert arguments to the correct types.  */
4883   if (!POINTER_TYPE_P (TREE_TYPE (dst)))
4884     dst = gfc_build_addr_expr (pvoid_type_node, dst);
4885   else
4886     dst = fold_convert (pvoid_type_node, dst);
4887
4888   if (!POINTER_TYPE_P (TREE_TYPE (src)))
4889     src = gfc_build_addr_expr (pvoid_type_node, src);
4890   else
4891     src = fold_convert (pvoid_type_node, src);
4892
4893   len = fold_convert (size_type_node, len);
4894
4895   /* Construct call to __builtin_memcpy.  */
4896   tmp = build_call_expr_loc (input_location,
4897                          built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
4898   return fold_convert (void_type_node, tmp);
4899 }
4900
4901
4902 /* Try to efficiently translate dst(:) = src(:).  Return NULL if this
4903    can't be done.  EXPR1 is the destination/lhs and EXPR2 is the
4904    source/rhs, both are gfc_full_array_ref_p which have been checked for
4905    dependencies.  */
4906
4907 static tree
4908 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
4909 {
4910   tree dst, dlen, dtype;
4911   tree src, slen, stype;
4912   tree tmp;
4913
4914   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
4915   src = gfc_get_symbol_decl (expr2->symtree->n.sym);
4916
4917   dtype = TREE_TYPE (dst);
4918   if (POINTER_TYPE_P (dtype))
4919     dtype = TREE_TYPE (dtype);
4920   stype = TREE_TYPE (src);
4921   if (POINTER_TYPE_P (stype))
4922     stype = TREE_TYPE (stype);
4923
4924   if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
4925     return NULL_TREE;
4926
4927   /* Determine the lengths of the arrays.  */
4928   dlen = GFC_TYPE_ARRAY_SIZE (dtype);
4929   if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
4930     return NULL_TREE;
4931   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
4932   dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
4933                       fold_convert (gfc_array_index_type, tmp));
4934
4935   slen = GFC_TYPE_ARRAY_SIZE (stype);
4936   if (!slen || TREE_CODE (slen) != INTEGER_CST)
4937     return NULL_TREE;
4938   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
4939   slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
4940                       fold_convert (gfc_array_index_type, tmp));
4941
4942   /* Sanity check that they are the same.  This should always be
4943      the case, as we should already have checked for conformance.  */
4944   if (!tree_int_cst_equal (slen, dlen))
4945     return NULL_TREE;
4946
4947   return gfc_build_memcpy_call (dst, src, dlen);
4948 }
4949
4950
4951 /* Try to efficiently translate array(:) = (/ ... /).  Return NULL if
4952    this can't be done.  EXPR1 is the destination/lhs for which
4953    gfc_full_array_ref_p is true, and EXPR2 is the source/rhs.  */
4954
4955 static tree
4956 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
4957 {
4958   unsigned HOST_WIDE_INT nelem;
4959   tree dst, dtype;
4960   tree src, stype;
4961   tree len;
4962   tree tmp;
4963
4964   nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
4965   if (nelem == 0)
4966     return NULL_TREE;
4967
4968   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
4969   dtype = TREE_TYPE (dst);
4970   if (POINTER_TYPE_P (dtype))
4971     dtype = TREE_TYPE (dtype);
4972   if (!GFC_ARRAY_TYPE_P (dtype))
4973     return NULL_TREE;
4974
4975   /* Determine the lengths of the array.  */
4976   len = GFC_TYPE_ARRAY_SIZE (dtype);
4977   if (!len || TREE_CODE (len) != INTEGER_CST)
4978     return NULL_TREE;
4979
4980   /* Confirm that the constructor is the same size.  */
4981   if (compare_tree_int (len, nelem) != 0)
4982     return NULL_TREE;
4983
4984   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
4985   len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
4986                      fold_convert (gfc_array_index_type, tmp));
4987
4988   stype = gfc_typenode_for_spec (&expr2->ts);
4989   src = gfc_build_constant_array_constructor (expr2, stype);
4990
4991   stype = TREE_TYPE (src);
4992   if (POINTER_TYPE_P (stype))
4993     stype = TREE_TYPE (stype);
4994
4995   return gfc_build_memcpy_call (dst, src, len);
4996 }
4997
4998
4999 /* Subroutine of gfc_trans_assignment that actually scalarizes the
5000    assignment.  EXPR1 is the destination/LHS and EXPR2 is the source/RHS.  */
5001
5002 static tree
5003 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
5004 {
5005   gfc_se lse;
5006   gfc_se rse;
5007   gfc_ss *lss;
5008   gfc_ss *lss_section;
5009   gfc_ss *rss;
5010   gfc_loopinfo loop;
5011   tree tmp;
5012   stmtblock_t block;
5013   stmtblock_t body;
5014   bool l_is_temp;
5015   bool scalar_to_array;
5016   tree string_length;
5017
5018   /* Assignment of the form lhs = rhs.  */
5019   gfc_start_block (&block);
5020
5021   gfc_init_se (&lse, NULL);
5022   gfc_init_se (&rse, NULL);
5023
5024   /* Walk the lhs.  */
5025   lss = gfc_walk_expr (expr1);
5026   rss = NULL;
5027   if (lss != gfc_ss_terminator)
5028     {
5029       /* Allow the scalarizer to workshare array assignments.  */
5030       if (ompws_flags & OMPWS_WORKSHARE_FLAG)
5031         ompws_flags |= OMPWS_SCALARIZER_WS;
5032
5033       /* The assignment needs scalarization.  */
5034       lss_section = lss;
5035
5036       /* Find a non-scalar SS from the lhs.  */
5037       while (lss_section != gfc_ss_terminator
5038              && lss_section->type != GFC_SS_SECTION)
5039         lss_section = lss_section->next;
5040
5041       gcc_assert (lss_section != gfc_ss_terminator);
5042
5043       /* Initialize the scalarizer.  */
5044       gfc_init_loopinfo (&loop);
5045
5046       /* Walk the rhs.  */
5047       rss = gfc_walk_expr (expr2);
5048       if (rss == gfc_ss_terminator)
5049         {
5050           /* The rhs is scalar.  Add a ss for the expression.  */
5051           rss = gfc_get_ss ();
5052           rss->next = gfc_ss_terminator;
5053           rss->type = GFC_SS_SCALAR;
5054           rss->expr = expr2;
5055         }
5056       /* Associate the SS with the loop.  */
5057       gfc_add_ss_to_loop (&loop, lss);
5058       gfc_add_ss_to_loop (&loop, rss);
5059
5060       /* Calculate the bounds of the scalarization.  */
5061       gfc_conv_ss_startstride (&loop);
5062       /* Resolve any data dependencies in the statement.  */
5063       gfc_conv_resolve_dependencies (&loop, lss, rss);
5064       /* Setup the scalarizing loops.  */
5065       gfc_conv_loop_setup (&loop, &expr2->where);
5066
5067       /* Setup the gfc_se structures.  */
5068       gfc_copy_loopinfo_to_se (&lse, &loop);
5069       gfc_copy_loopinfo_to_se (&rse, &loop);
5070
5071       rse.ss = rss;
5072       gfc_mark_ss_chain_used (rss, 1);
5073       if (loop.temp_ss == NULL)
5074         {
5075           lse.ss = lss;
5076           gfc_mark_ss_chain_used (lss, 1);
5077         }
5078       else
5079         {
5080           lse.ss = loop.temp_ss;
5081           gfc_mark_ss_chain_used (lss, 3);
5082           gfc_mark_ss_chain_used (loop.temp_ss, 3);
5083         }
5084
5085       /* Start the scalarized loop body.  */
5086       gfc_start_scalarized_body (&loop, &body);
5087     }
5088   else
5089     gfc_init_block (&body);
5090
5091   l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
5092
5093   /* Translate the expression.  */
5094   gfc_conv_expr (&rse, expr2);
5095
5096   /* Stabilize a string length for temporaries.  */
5097   if (expr2->ts.type == BT_CHARACTER)
5098     string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
5099   else
5100     string_length = NULL_TREE;
5101
5102   if (l_is_temp)
5103     {
5104       gfc_conv_tmp_array_ref (&lse);
5105       gfc_advance_se_ss_chain (&lse);
5106       if (expr2->ts.type == BT_CHARACTER)
5107         lse.string_length = string_length;
5108     }
5109   else
5110     gfc_conv_expr (&lse, expr1);
5111
5112   /* Assignments of scalar derived types with allocatable components
5113      to arrays must be done with a deep copy and the rhs temporary
5114      must have its components deallocated afterwards.  */
5115   scalar_to_array = (expr2->ts.type == BT_DERIVED
5116                        && expr2->ts.u.derived->attr.alloc_comp
5117                        && expr2->expr_type != EXPR_VARIABLE
5118                        && !gfc_is_constant_expr (expr2)
5119                        && expr1->rank && !expr2->rank);
5120   if (scalar_to_array)
5121     {
5122       tmp = gfc_deallocate_alloc_comp (expr2->ts.u.derived, rse.expr, 0);
5123       gfc_add_expr_to_block (&loop.post, tmp);
5124     }
5125
5126   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5127                                  l_is_temp || init_flag,
5128                                  (expr2->expr_type == EXPR_VARIABLE)
5129                                     || scalar_to_array);
5130   gfc_add_expr_to_block (&body, tmp);
5131
5132   if (lss == gfc_ss_terminator)
5133     {
5134       /* Use the scalar assignment as is.  */
5135       gfc_add_block_to_block (&block, &body);
5136     }
5137   else
5138     {
5139       gcc_assert (lse.ss == gfc_ss_terminator
5140                   && rse.ss == gfc_ss_terminator);
5141
5142       if (l_is_temp)
5143         {
5144           gfc_trans_scalarized_loop_boundary (&loop, &body);
5145
5146           /* We need to copy the temporary to the actual lhs.  */
5147           gfc_init_se (&lse, NULL);
5148           gfc_init_se (&rse, NULL);
5149           gfc_copy_loopinfo_to_se (&lse, &loop);
5150           gfc_copy_loopinfo_to_se (&rse, &loop);
5151
5152           rse.ss = loop.temp_ss;
5153           lse.ss = lss;
5154
5155           gfc_conv_tmp_array_ref (&rse);
5156           gfc_advance_se_ss_chain (&rse);
5157           gfc_conv_expr (&lse, expr1);
5158
5159           gcc_assert (lse.ss == gfc_ss_terminator
5160                       && rse.ss == gfc_ss_terminator);
5161
5162           if (expr2->ts.type == BT_CHARACTER)
5163             rse.string_length = string_length;
5164
5165           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5166                                          false, false);
5167           gfc_add_expr_to_block (&body, tmp);
5168         }
5169
5170       /* Generate the copying loops.  */
5171       gfc_trans_scalarizing_loops (&loop, &body);
5172
5173       /* Wrap the whole thing up.  */
5174       gfc_add_block_to_block (&block, &loop.pre);
5175       gfc_add_block_to_block (&block, &loop.post);
5176
5177       gfc_cleanup_loop (&loop);
5178     }
5179
5180   return gfc_finish_block (&block);
5181 }
5182
5183
5184 /* Check whether EXPR is a copyable array.  */
5185
5186 static bool
5187 copyable_array_p (gfc_expr * expr)
5188 {
5189   if (expr->expr_type != EXPR_VARIABLE)
5190     return false;
5191
5192   /* First check it's an array.  */
5193   if (expr->rank < 1 || !expr->ref || expr->ref->next)
5194     return false;
5195
5196   if (!gfc_full_array_ref_p (expr->ref, NULL))
5197     return false;
5198
5199   /* Next check that it's of a simple enough type.  */
5200   switch (expr->ts.type)
5201     {
5202     case BT_INTEGER:
5203     case BT_REAL:
5204     case BT_COMPLEX:
5205     case BT_LOGICAL:
5206       return true;
5207
5208     case BT_CHARACTER:
5209       return false;
5210
5211     case BT_DERIVED:
5212       return !expr->ts.u.derived->attr.alloc_comp;
5213
5214     default:
5215       break;
5216     }
5217
5218   return false;
5219 }
5220
5221 /* Translate an assignment.  */
5222
5223 tree
5224 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
5225 {
5226   tree tmp;
5227
5228   /* Special case a single function returning an array.  */
5229   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5230     {
5231       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5232       if (tmp)
5233         return tmp;
5234     }
5235
5236   /* Special case assigning an array to zero.  */
5237   if (copyable_array_p (expr1)
5238       && is_zero_initializer_p (expr2))
5239     {
5240       tmp = gfc_trans_zero_assign (expr1);
5241       if (tmp)
5242         return tmp;
5243     }
5244
5245   /* Special case copying one array to another.  */
5246   if (copyable_array_p (expr1)
5247       && copyable_array_p (expr2)
5248       && gfc_compare_types (&expr1->ts, &expr2->ts)
5249       && !gfc_check_dependency (expr1, expr2, 0))
5250     {
5251       tmp = gfc_trans_array_copy (expr1, expr2);
5252       if (tmp)
5253         return tmp;
5254     }
5255
5256   /* Special case initializing an array from a constant array constructor.  */
5257   if (copyable_array_p (expr1)
5258       && expr2->expr_type == EXPR_ARRAY
5259       && gfc_compare_types (&expr1->ts, &expr2->ts))
5260     {
5261       tmp = gfc_trans_array_constructor_copy (expr1, expr2);
5262       if (tmp)
5263         return tmp;
5264     }
5265
5266   /* Fallback to the scalarizer to generate explicit loops.  */
5267   return gfc_trans_assignment_1 (expr1, expr2, init_flag);
5268 }
5269
5270 tree
5271 gfc_trans_init_assign (gfc_code * code)
5272 {
5273   return gfc_trans_assignment (code->expr1, code->expr2, true);
5274 }
5275
5276 tree
5277 gfc_trans_assign (gfc_code * code)
5278 {
5279   return gfc_trans_assignment (code->expr1, code->expr2, false);
5280 }
5281
5282
5283 /* Translate an assignment to a CLASS object
5284    (pointer or ordinary assignment).  */
5285
5286 tree
5287 gfc_trans_class_assign (gfc_code *code)
5288 {
5289   stmtblock_t block;
5290   tree tmp;
5291
5292   gfc_start_block (&block);
5293
5294   if (code->expr2->ts.type != BT_CLASS)
5295     {
5296       /* Insert an additional assignment which sets the '$vindex' field.  */
5297       gfc_expr *lhs,*rhs;
5298       lhs = gfc_copy_expr (code->expr1);
5299       gfc_add_component_ref (lhs, "$vindex");
5300       if (code->expr2->ts.type == BT_DERIVED)
5301         /* vindex is constant, determined at compile time.  */
5302         rhs = gfc_int_expr (code->expr2->ts.u.derived->vindex);
5303       else if (code->expr2->expr_type == EXPR_NULL)
5304         rhs = gfc_int_expr (0);
5305       else
5306         gcc_unreachable ();
5307       tmp = gfc_trans_assignment (lhs, rhs, false);
5308       gfc_add_expr_to_block (&block, tmp);
5309
5310       /* Insert another assignment which sets the '$size' field.  */
5311       lhs = gfc_copy_expr (code->expr1);
5312       gfc_add_component_ref (lhs, "$size");
5313       if (code->expr2->ts.type == BT_DERIVED)
5314         {
5315           /* Size is fixed at compile time.  */
5316           gfc_se lse;
5317           gfc_init_se (&lse, NULL);
5318           gfc_conv_expr (&lse, lhs);
5319           tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->expr2->ts));
5320           gfc_add_modify (&block, lse.expr,
5321                           fold_convert (TREE_TYPE (lse.expr), tmp));
5322         }
5323       else if (code->expr2->expr_type == EXPR_NULL)
5324         {
5325           rhs = gfc_int_expr (0);
5326           tmp = gfc_trans_assignment (lhs, rhs, false);
5327           gfc_add_expr_to_block (&block, tmp);
5328         }
5329       else
5330         gcc_unreachable ();
5331
5332       gfc_free_expr (lhs);
5333       gfc_free_expr (rhs);
5334     }
5335
5336   /* Do the actual CLASS assignment.  */
5337   if (code->expr2->ts.type == BT_CLASS)
5338     code->op = EXEC_ASSIGN;
5339   else
5340     gfc_add_component_ref (code->expr1, "$data");
5341
5342   if (code->op == EXEC_ASSIGN)
5343     tmp = gfc_trans_assign (code);
5344   else if (code->op == EXEC_POINTER_ASSIGN)
5345     tmp = gfc_trans_pointer_assign (code);
5346   else
5347     gcc_unreachable();
5348
5349   gfc_add_expr_to_block (&block, tmp);
5350
5351   return gfc_finish_block (&block);
5352 }