OSDN Git Service

2009-11-01 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                   if (fsym->attr.optional
2947                       && e->expr_type == EXPR_VARIABLE
2948                       && e->symtree->n.sym->attr.optional)
2949                     tmp = fold_build3 (COND_EXPR, void_type_node,
2950                                      gfc_conv_expr_present (e->symtree->n.sym),
2951                                        tmp, build_empty_stmt (input_location));
2952                   gfc_add_expr_to_block (&se->pre, tmp);
2953                 }
2954             } 
2955         }
2956
2957       /* The case with fsym->attr.optional is that of a user subroutine
2958          with an interface indicating an optional argument.  When we call
2959          an intrinsic subroutine, however, fsym is NULL, but we might still
2960          have an optional argument, so we proceed to the substitution
2961          just in case.  */
2962       if (e && (fsym == NULL || fsym->attr.optional))
2963         {
2964           /* If an optional argument is itself an optional dummy argument,
2965              check its presence and substitute a null if absent.  This is
2966              only needed when passing an array to an elemental procedure
2967              as then array elements are accessed - or no NULL pointer is
2968              allowed and a "1" or "0" should be passed if not present.
2969              When passing a deferred array to a non-deferred array dummy,
2970              the array needs to be packed and a check needs thus to be
2971              inserted.  */
2972           if (e->expr_type == EXPR_VARIABLE
2973               && e->symtree->n.sym->attr.optional
2974               && ((e->rank > 0 && sym->attr.elemental)
2975                   || e->representation.length || e->ts.type == BT_CHARACTER
2976                   || (e->rank > 0 && (fsym == NULL
2977                                       || (fsym->as->type != AS_ASSUMED_SHAPE
2978                                           && fsym->as->type != AS_DEFERRED)))))
2979             gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
2980                                     e->representation.length);
2981         }
2982
2983       if (fsym && e)
2984         {
2985           /* Obtain the character length of an assumed character length
2986              length procedure from the typespec.  */
2987           if (fsym->ts.type == BT_CHARACTER
2988               && parmse.string_length == NULL_TREE
2989               && e->ts.type == BT_PROCEDURE
2990               && e->symtree->n.sym->ts.type == BT_CHARACTER
2991               && e->symtree->n.sym->ts.u.cl->length != NULL
2992               && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
2993             {
2994               gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
2995               parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
2996             }
2997         }
2998
2999       if (fsym && need_interface_mapping && e)
3000         gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
3001
3002       gfc_add_block_to_block (&se->pre, &parmse.pre);
3003       gfc_add_block_to_block (&post, &parmse.post);
3004
3005       /* Allocated allocatable components of derived types must be
3006          deallocated for non-variable scalars.  Non-variable arrays are
3007          dealt with in trans-array.c(gfc_conv_array_parameter).  */
3008       if (e && e->ts.type == BT_DERIVED
3009             && e->ts.u.derived->attr.alloc_comp
3010             && !(e->symtree && e->symtree->n.sym->attr.pointer)
3011             && (e->expr_type != EXPR_VARIABLE && !e->rank))
3012         {
3013           int parm_rank;
3014           tmp = build_fold_indirect_ref_loc (input_location,
3015                                          parmse.expr);
3016           parm_rank = e->rank;
3017           switch (parm_kind)
3018             {
3019             case (ELEMENTAL):
3020             case (SCALAR):
3021               parm_rank = 0;
3022               break;
3023
3024             case (SCALAR_POINTER):
3025               tmp = build_fold_indirect_ref_loc (input_location,
3026                                              tmp);
3027               break;
3028             }
3029
3030           if (e->expr_type == EXPR_OP
3031                 && e->value.op.op == INTRINSIC_PARENTHESES
3032                 && e->value.op.op1->expr_type == EXPR_VARIABLE)
3033             {
3034               tree local_tmp;
3035               local_tmp = gfc_evaluate_now (tmp, &se->pre);
3036               local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
3037               gfc_add_expr_to_block (&se->post, local_tmp);
3038             }
3039
3040           tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
3041
3042           gfc_add_expr_to_block (&se->post, tmp);
3043         }
3044
3045       /* Add argument checking of passing an unallocated/NULL actual to
3046          a nonallocatable/nonpointer dummy.  */
3047
3048       if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
3049         {
3050           symbol_attribute *attr;
3051           char *msg;
3052           tree cond;
3053
3054           if (e->expr_type == EXPR_VARIABLE)
3055             attr = &e->symtree->n.sym->attr;
3056           else if (e->expr_type == EXPR_FUNCTION)
3057             {
3058               /* For intrinsic functions, the gfc_attr are not available.  */
3059               if (e->symtree->n.sym->attr.generic && e->value.function.isym)
3060                 goto end_pointer_check;
3061
3062               if (e->symtree->n.sym->attr.generic)
3063                 attr = &e->value.function.esym->attr;
3064               else
3065                 attr = &e->symtree->n.sym->result->attr;
3066             }
3067           else
3068             goto end_pointer_check;
3069
3070           if (attr->optional)
3071             {
3072               /* If the actual argument is an optional pointer/allocatable and
3073                  the formal argument takes an nonpointer optional value,
3074                  it is invalid to pass a non-present argument on, even
3075                  though there is no technical reason for this in gfortran.
3076                  See Fortran 2003, Section 12.4.1.6 item (7)+(8).  */
3077               tree present, nullptr, type;
3078
3079               if (attr->allocatable
3080                   && (fsym == NULL || !fsym->attr.allocatable))
3081                 asprintf (&msg, "Allocatable actual argument '%s' is not "
3082                           "allocated or not present", e->symtree->n.sym->name);
3083               else if (attr->pointer
3084                        && (fsym == NULL || !fsym->attr.pointer))
3085                 asprintf (&msg, "Pointer actual argument '%s' is not "
3086                           "associated or not present",
3087                           e->symtree->n.sym->name);
3088               else if (attr->proc_pointer
3089                        && (fsym == NULL || !fsym->attr.proc_pointer))
3090                 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3091                           "associated or not present",
3092                           e->symtree->n.sym->name);
3093               else
3094                 goto end_pointer_check;
3095
3096               present = gfc_conv_expr_present (e->symtree->n.sym);
3097               type = TREE_TYPE (present);
3098               present = fold_build2 (EQ_EXPR, boolean_type_node, present,
3099                                      fold_convert (type, null_pointer_node));
3100               type = TREE_TYPE (parmse.expr);
3101               nullptr = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3102                                      fold_convert (type, null_pointer_node));
3103               cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node,
3104                                   present, nullptr);
3105             }
3106           else
3107             {
3108               if (attr->allocatable
3109                   && (fsym == NULL || !fsym->attr.allocatable))
3110                 asprintf (&msg, "Allocatable actual argument '%s' is not "
3111                       "allocated", e->symtree->n.sym->name);
3112               else if (attr->pointer
3113                        && (fsym == NULL || !fsym->attr.pointer))
3114                 asprintf (&msg, "Pointer actual argument '%s' is not "
3115                       "associated", e->symtree->n.sym->name);
3116               else if (attr->proc_pointer
3117                        && (fsym == NULL || !fsym->attr.proc_pointer))
3118                 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3119                       "associated", e->symtree->n.sym->name);
3120               else
3121                 goto end_pointer_check;
3122
3123
3124               cond = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3125                                   fold_convert (TREE_TYPE (parmse.expr),
3126                                                 null_pointer_node));
3127             }
3128  
3129           gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
3130                                    msg);
3131           gfc_free (msg);
3132         }
3133       end_pointer_check:
3134
3135
3136       /* Character strings are passed as two parameters, a length and a
3137          pointer - except for Bind(c) which only passes the pointer.  */
3138       if (parmse.string_length != NULL_TREE && !sym->attr.is_bind_c)
3139         stringargs = gfc_chainon_list (stringargs, parmse.string_length);
3140
3141       arglist = gfc_chainon_list (arglist, parmse.expr);
3142     }
3143   gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
3144
3145   if (comp)
3146     ts = comp->ts;
3147   else
3148    ts = sym->ts;
3149
3150   if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
3151     se->string_length = build_int_cst (gfc_charlen_type_node, 1);
3152   else if (ts.type == BT_CHARACTER)
3153     {
3154       if (ts.u.cl->length == NULL)
3155         {
3156           /* Assumed character length results are not allowed by 5.1.1.5 of the
3157              standard and are trapped in resolve.c; except in the case of SPREAD
3158              (and other intrinsics?) and dummy functions.  In the case of SPREAD,
3159              we take the character length of the first argument for the result.
3160              For dummies, we have to look through the formal argument list for
3161              this function and use the character length found there.*/
3162           if (!sym->attr.dummy)
3163             cl.backend_decl = TREE_VALUE (stringargs);
3164           else
3165             {
3166               formal = sym->ns->proc_name->formal;
3167               for (; formal; formal = formal->next)
3168                 if (strcmp (formal->sym->name, sym->name) == 0)
3169                   cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
3170             }
3171         }
3172         else
3173         {
3174           tree tmp;
3175
3176           /* Calculate the length of the returned string.  */
3177           gfc_init_se (&parmse, NULL);
3178           if (need_interface_mapping)
3179             gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
3180           else
3181             gfc_conv_expr (&parmse, ts.u.cl->length);
3182           gfc_add_block_to_block (&se->pre, &parmse.pre);
3183           gfc_add_block_to_block (&se->post, &parmse.post);
3184           
3185           tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
3186           tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
3187                              build_int_cst (gfc_charlen_type_node, 0));
3188           cl.backend_decl = tmp;
3189         }
3190
3191       /* Set up a charlen structure for it.  */
3192       cl.next = NULL;
3193       cl.length = NULL;
3194       ts.u.cl = &cl;
3195
3196       len = cl.backend_decl;
3197     }
3198
3199   byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
3200           || (!comp && gfc_return_by_reference (sym));
3201   if (byref)
3202     {
3203       if (se->direct_byref)
3204         {
3205           /* Sometimes, too much indirection can be applied; e.g. for
3206              function_result = array_valued_recursive_function.  */
3207           if (TREE_TYPE (TREE_TYPE (se->expr))
3208                 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
3209                 && GFC_DESCRIPTOR_TYPE_P
3210                         (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
3211             se->expr = build_fold_indirect_ref_loc (input_location,
3212                                                 se->expr);
3213
3214           retargs = gfc_chainon_list (retargs, se->expr);
3215         }
3216       else if (comp && comp->attr.dimension)
3217         {
3218           gcc_assert (se->loop && info);
3219
3220           /* Set the type of the array.  */
3221           tmp = gfc_typenode_for_spec (&comp->ts);
3222           info->dimen = se->loop->dimen;
3223
3224           /* Evaluate the bounds of the result, if known.  */
3225           gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
3226
3227           /* Create a temporary to store the result.  In case the function
3228              returns a pointer, the temporary will be a shallow copy and
3229              mustn't be deallocated.  */
3230           callee_alloc = comp->attr.allocatable || comp->attr.pointer;
3231           gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
3232                                        NULL_TREE, false, !comp->attr.pointer,
3233                                        callee_alloc, &se->ss->expr->where);
3234
3235           /* Pass the temporary as the first argument.  */
3236           tmp = info->descriptor;
3237           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3238           retargs = gfc_chainon_list (retargs, tmp);
3239         }
3240       else if (!comp && sym->result->attr.dimension)
3241         {
3242           gcc_assert (se->loop && info);
3243
3244           /* Set the type of the array.  */
3245           tmp = gfc_typenode_for_spec (&ts);
3246           info->dimen = se->loop->dimen;
3247
3248           /* Evaluate the bounds of the result, if known.  */
3249           gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
3250
3251           /* Create a temporary to store the result.  In case the function
3252              returns a pointer, the temporary will be a shallow copy and
3253              mustn't be deallocated.  */
3254           callee_alloc = sym->attr.allocatable || sym->attr.pointer;
3255           gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
3256                                        NULL_TREE, false, !sym->attr.pointer,
3257                                        callee_alloc, &se->ss->expr->where);
3258
3259           /* Pass the temporary as the first argument.  */
3260           tmp = info->descriptor;
3261           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3262           retargs = gfc_chainon_list (retargs, tmp);
3263         }
3264       else if (ts.type == BT_CHARACTER)
3265         {
3266           /* Pass the string length.  */
3267           type = gfc_get_character_type (ts.kind, ts.u.cl);
3268           type = build_pointer_type (type);
3269
3270           /* Return an address to a char[0:len-1]* temporary for
3271              character pointers.  */
3272           if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3273                || (comp && (comp->attr.pointer || comp->attr.allocatable)))
3274             {
3275               var = gfc_create_var (type, "pstr");
3276
3277               /* Provide an address expression for the function arguments.  */
3278               var = gfc_build_addr_expr (NULL_TREE, var);
3279             }
3280           else
3281             var = gfc_conv_string_tmp (se, type, len);
3282
3283           retargs = gfc_chainon_list (retargs, var);
3284         }
3285       else
3286         {
3287           gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
3288
3289           type = gfc_get_complex_type (ts.kind);
3290           var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
3291           retargs = gfc_chainon_list (retargs, var);
3292         }
3293
3294       /* Add the string length to the argument list.  */
3295       if (ts.type == BT_CHARACTER)
3296         retargs = gfc_chainon_list (retargs, len);
3297     }
3298   gfc_free_interface_mapping (&mapping);
3299
3300   /* Add the return arguments.  */
3301   arglist = chainon (retargs, arglist);
3302
3303   /* Add the hidden string length parameters to the arguments.  */
3304   arglist = chainon (arglist, stringargs);
3305
3306   /* We may want to append extra arguments here.  This is used e.g. for
3307      calls to libgfortran_matmul_??, which need extra information.  */
3308   if (append_args != NULL_TREE)
3309     arglist = chainon (arglist, append_args);
3310
3311   /* Generate the actual call.  */
3312   conv_function_val (se, sym, expr);
3313
3314   /* If there are alternate return labels, function type should be
3315      integer.  Can't modify the type in place though, since it can be shared
3316      with other functions.  For dummy arguments, the typing is done to
3317      to this result, even if it has to be repeated for each call.  */
3318   if (has_alternate_specifier
3319       && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
3320     {
3321       if (!sym->attr.dummy)
3322         {
3323           TREE_TYPE (sym->backend_decl)
3324                 = build_function_type (integer_type_node,
3325                       TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
3326           se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
3327         }
3328       else
3329         TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
3330     }
3331
3332   fntype = TREE_TYPE (TREE_TYPE (se->expr));
3333   se->expr = build_call_list (TREE_TYPE (fntype), se->expr, arglist);
3334
3335   /* If we have a pointer function, but we don't want a pointer, e.g.
3336      something like
3337         x = f()
3338      where f is pointer valued, we have to dereference the result.  */
3339   if (!se->want_pointer && !byref && sym->attr.pointer
3340       && !gfc_is_proc_ptr_comp (expr, NULL))
3341     se->expr = build_fold_indirect_ref_loc (input_location,
3342                                         se->expr);
3343
3344   /* f2c calling conventions require a scalar default real function to
3345      return a double precision result.  Convert this back to default
3346      real.  We only care about the cases that can happen in Fortran 77.
3347   */
3348   if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
3349       && sym->ts.kind == gfc_default_real_kind
3350       && !sym->attr.always_explicit)
3351     se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
3352
3353   /* A pure function may still have side-effects - it may modify its
3354      parameters.  */
3355   TREE_SIDE_EFFECTS (se->expr) = 1;
3356 #if 0
3357   if (!sym->attr.pure)
3358     TREE_SIDE_EFFECTS (se->expr) = 1;
3359 #endif
3360
3361   if (byref)
3362     {
3363       /* Add the function call to the pre chain.  There is no expression.  */
3364       gfc_add_expr_to_block (&se->pre, se->expr);
3365       se->expr = NULL_TREE;
3366
3367       if (!se->direct_byref)
3368         {
3369           if (sym->attr.dimension || (comp && comp->attr.dimension))
3370             {
3371               if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3372                 {
3373                   /* Check the data pointer hasn't been modified.  This would
3374                      happen in a function returning a pointer.  */
3375                   tmp = gfc_conv_descriptor_data_get (info->descriptor);
3376                   tmp = fold_build2 (NE_EXPR, boolean_type_node,
3377                                      tmp, info->data);
3378                   gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
3379                                            gfc_msg_fault);
3380                 }
3381               se->expr = info->descriptor;
3382               /* Bundle in the string length.  */
3383               se->string_length = len;
3384             }
3385           else if (ts.type == BT_CHARACTER)
3386             {
3387               /* Dereference for character pointer results.  */
3388               if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3389                   || (comp && (comp->attr.pointer || comp->attr.allocatable)))
3390                 se->expr = build_fold_indirect_ref_loc (input_location, var);
3391               else
3392                 se->expr = var;
3393
3394               se->string_length = len;
3395             }
3396           else
3397             {
3398               gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
3399               se->expr = build_fold_indirect_ref_loc (input_location, var);
3400             }
3401         }
3402     }
3403
3404   /* Follow the function call with the argument post block.  */
3405   if (byref)
3406     gfc_add_block_to_block (&se->pre, &post);
3407   else
3408     gfc_add_block_to_block (&se->post, &post);
3409
3410   return has_alternate_specifier;
3411 }
3412
3413
3414 /* Fill a character string with spaces.  */
3415
3416 static tree
3417 fill_with_spaces (tree start, tree type, tree size)
3418 {
3419   stmtblock_t block, loop;
3420   tree i, el, exit_label, cond, tmp;
3421
3422   /* For a simple char type, we can call memset().  */
3423   if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
3424     return build_call_expr_loc (input_location,
3425                             built_in_decls[BUILT_IN_MEMSET], 3, start,
3426                             build_int_cst (gfc_get_int_type (gfc_c_int_kind),
3427                                            lang_hooks.to_target_charset (' ')),
3428                             size);
3429
3430   /* Otherwise, we use a loop:
3431         for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
3432           *el = (type) ' ';
3433    */
3434
3435   /* Initialize variables.  */
3436   gfc_init_block (&block);
3437   i = gfc_create_var (sizetype, "i");
3438   gfc_add_modify (&block, i, fold_convert (sizetype, size));
3439   el = gfc_create_var (build_pointer_type (type), "el");
3440   gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
3441   exit_label = gfc_build_label_decl (NULL_TREE);
3442   TREE_USED (exit_label) = 1;
3443
3444
3445   /* Loop body.  */
3446   gfc_init_block (&loop);
3447
3448   /* Exit condition.  */
3449   cond = fold_build2 (LE_EXPR, boolean_type_node, i,
3450                       fold_convert (sizetype, integer_zero_node));
3451   tmp = build1_v (GOTO_EXPR, exit_label);
3452   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3453                      build_empty_stmt (input_location));
3454   gfc_add_expr_to_block (&loop, tmp);
3455
3456   /* Assignment.  */
3457   gfc_add_modify (&loop, fold_build1 (INDIRECT_REF, type, el),
3458                        build_int_cst (type,
3459                                       lang_hooks.to_target_charset (' ')));
3460
3461   /* Increment loop variables.  */
3462   gfc_add_modify (&loop, i, fold_build2 (MINUS_EXPR, sizetype, i,
3463                                               TYPE_SIZE_UNIT (type)));
3464   gfc_add_modify (&loop, el, fold_build2 (POINTER_PLUS_EXPR,
3465                                                TREE_TYPE (el), el,
3466                                                TYPE_SIZE_UNIT (type)));
3467
3468   /* Making the loop... actually loop!  */
3469   tmp = gfc_finish_block (&loop);
3470   tmp = build1_v (LOOP_EXPR, tmp);
3471   gfc_add_expr_to_block (&block, tmp);
3472
3473   /* The exit label.  */
3474   tmp = build1_v (LABEL_EXPR, exit_label);
3475   gfc_add_expr_to_block (&block, tmp);
3476
3477
3478   return gfc_finish_block (&block);
3479 }
3480
3481
3482 /* Generate code to copy a string.  */
3483
3484 void
3485 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
3486                        int dkind, tree slength, tree src, int skind)
3487 {
3488   tree tmp, dlen, slen;
3489   tree dsc;
3490   tree ssc;
3491   tree cond;
3492   tree cond2;
3493   tree tmp2;
3494   tree tmp3;
3495   tree tmp4;
3496   tree chartype;
3497   stmtblock_t tempblock;
3498
3499   gcc_assert (dkind == skind);
3500
3501   if (slength != NULL_TREE)
3502     {
3503       slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
3504       ssc = string_to_single_character (slen, src, skind);
3505     }
3506   else
3507     {
3508       slen = build_int_cst (size_type_node, 1);
3509       ssc =  src;
3510     }
3511
3512   if (dlength != NULL_TREE)
3513     {
3514       dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
3515       dsc = string_to_single_character (slen, dest, dkind);
3516     }
3517   else
3518     {
3519       dlen = build_int_cst (size_type_node, 1);
3520       dsc =  dest;
3521     }
3522
3523   if (slength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (src)))
3524     ssc = string_to_single_character (slen, src, skind);
3525   if (dlength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (dest)))
3526     dsc = string_to_single_character (dlen, dest, dkind);
3527
3528
3529   /* Assign directly if the types are compatible.  */
3530   if (dsc != NULL_TREE && ssc != NULL_TREE
3531       && TREE_TYPE (dsc) == TREE_TYPE (ssc))
3532     {
3533       gfc_add_modify (block, dsc, ssc);
3534       return;
3535     }
3536
3537   /* Do nothing if the destination length is zero.  */
3538   cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
3539                       build_int_cst (size_type_node, 0));
3540
3541   /* The following code was previously in _gfortran_copy_string:
3542
3543        // The two strings may overlap so we use memmove.
3544        void
3545        copy_string (GFC_INTEGER_4 destlen, char * dest,
3546                     GFC_INTEGER_4 srclen, const char * src)
3547        {
3548          if (srclen >= destlen)
3549            {
3550              // This will truncate if too long.
3551              memmove (dest, src, destlen);
3552            }
3553          else
3554            {
3555              memmove (dest, src, srclen);
3556              // Pad with spaces.
3557              memset (&dest[srclen], ' ', destlen - srclen);
3558            }
3559        }
3560
3561      We're now doing it here for better optimization, but the logic
3562      is the same.  */
3563
3564   /* For non-default character kinds, we have to multiply the string
3565      length by the base type size.  */
3566   chartype = gfc_get_char_type (dkind);
3567   slen = fold_build2 (MULT_EXPR, size_type_node,
3568                       fold_convert (size_type_node, slen),
3569                       fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
3570   dlen = fold_build2 (MULT_EXPR, size_type_node,
3571                       fold_convert (size_type_node, dlen),
3572                       fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
3573
3574   if (dlength)
3575     dest = fold_convert (pvoid_type_node, dest);
3576   else
3577     dest = gfc_build_addr_expr (pvoid_type_node, dest);
3578
3579   if (slength)
3580     src = fold_convert (pvoid_type_node, src);
3581   else
3582     src = gfc_build_addr_expr (pvoid_type_node, src);
3583
3584   /* Truncate string if source is too long.  */
3585   cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
3586   tmp2 = build_call_expr_loc (input_location,
3587                           built_in_decls[BUILT_IN_MEMMOVE],
3588                           3, dest, src, dlen);
3589
3590   /* Else copy and pad with spaces.  */
3591   tmp3 = build_call_expr_loc (input_location,
3592                           built_in_decls[BUILT_IN_MEMMOVE],
3593                           3, dest, src, slen);
3594
3595   tmp4 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest,
3596                       fold_convert (sizetype, slen));
3597   tmp4 = fill_with_spaces (tmp4, chartype,
3598                            fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
3599                                         dlen, slen));
3600
3601   gfc_init_block (&tempblock);
3602   gfc_add_expr_to_block (&tempblock, tmp3);
3603   gfc_add_expr_to_block (&tempblock, tmp4);
3604   tmp3 = gfc_finish_block (&tempblock);
3605
3606   /* The whole copy_string function is there.  */
3607   tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
3608   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3609                      build_empty_stmt (input_location));
3610   gfc_add_expr_to_block (block, tmp);
3611 }
3612
3613
3614 /* Translate a statement function.
3615    The value of a statement function reference is obtained by evaluating the
3616    expression using the values of the actual arguments for the values of the
3617    corresponding dummy arguments.  */
3618
3619 static void
3620 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
3621 {
3622   gfc_symbol *sym;
3623   gfc_symbol *fsym;
3624   gfc_formal_arglist *fargs;
3625   gfc_actual_arglist *args;
3626   gfc_se lse;
3627   gfc_se rse;
3628   gfc_saved_var *saved_vars;
3629   tree *temp_vars;
3630   tree type;
3631   tree tmp;
3632   int n;
3633
3634   sym = expr->symtree->n.sym;
3635   args = expr->value.function.actual;
3636   gfc_init_se (&lse, NULL);
3637   gfc_init_se (&rse, NULL);
3638
3639   n = 0;
3640   for (fargs = sym->formal; fargs; fargs = fargs->next)
3641     n++;
3642   saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
3643   temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
3644
3645   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3646     {
3647       /* Each dummy shall be specified, explicitly or implicitly, to be
3648          scalar.  */
3649       gcc_assert (fargs->sym->attr.dimension == 0);
3650       fsym = fargs->sym;
3651
3652       /* Create a temporary to hold the value.  */
3653       type = gfc_typenode_for_spec (&fsym->ts);
3654       temp_vars[n] = gfc_create_var (type, fsym->name);
3655
3656       if (fsym->ts.type == BT_CHARACTER)
3657         {
3658           /* Copy string arguments.  */
3659           tree arglen;
3660
3661           gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
3662                       && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
3663
3664           arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3665           tmp = gfc_build_addr_expr (build_pointer_type (type),
3666                                      temp_vars[n]);
3667
3668           gfc_conv_expr (&rse, args->expr);
3669           gfc_conv_string_parameter (&rse);
3670           gfc_add_block_to_block (&se->pre, &lse.pre);
3671           gfc_add_block_to_block (&se->pre, &rse.pre);
3672
3673           gfc_trans_string_copy (&se->pre, arglen, tmp, fsym->ts.kind,
3674                                  rse.string_length, rse.expr, fsym->ts.kind);
3675           gfc_add_block_to_block (&se->pre, &lse.post);
3676           gfc_add_block_to_block (&se->pre, &rse.post);
3677         }
3678       else
3679         {
3680           /* For everything else, just evaluate the expression.  */
3681           gfc_conv_expr (&lse, args->expr);
3682
3683           gfc_add_block_to_block (&se->pre, &lse.pre);
3684           gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
3685           gfc_add_block_to_block (&se->pre, &lse.post);
3686         }
3687
3688       args = args->next;
3689     }
3690
3691   /* Use the temporary variables in place of the real ones.  */
3692   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3693     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
3694
3695   gfc_conv_expr (se, sym->value);
3696
3697   if (sym->ts.type == BT_CHARACTER)
3698     {
3699       gfc_conv_const_charlen (sym->ts.u.cl);
3700
3701       /* Force the expression to the correct length.  */
3702       if (!INTEGER_CST_P (se->string_length)
3703           || tree_int_cst_lt (se->string_length,
3704                               sym->ts.u.cl->backend_decl))
3705         {
3706           type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
3707           tmp = gfc_create_var (type, sym->name);
3708           tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
3709           gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
3710                                  sym->ts.kind, se->string_length, se->expr,
3711                                  sym->ts.kind);
3712           se->expr = tmp;
3713         }
3714       se->string_length = sym->ts.u.cl->backend_decl;
3715     }
3716
3717   /* Restore the original variables.  */
3718   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3719     gfc_restore_sym (fargs->sym, &saved_vars[n]);
3720   gfc_free (saved_vars);
3721 }
3722
3723
3724 /* Translate a function expression.  */
3725
3726 static void
3727 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
3728 {
3729   gfc_symbol *sym;
3730
3731   if (expr->value.function.isym)
3732     {
3733       gfc_conv_intrinsic_function (se, expr);
3734       return;
3735     }
3736
3737   /* We distinguish statement functions from general functions to improve
3738      runtime performance.  */
3739   if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
3740     {
3741       gfc_conv_statement_function (se, expr);
3742       return;
3743     }
3744
3745   /* expr.value.function.esym is the resolved (specific) function symbol for
3746      most functions.  However this isn't set for dummy procedures.  */
3747   sym = expr->value.function.esym;
3748   if (!sym)
3749     sym = expr->symtree->n.sym;
3750
3751   gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
3752                           NULL_TREE);
3753 }
3754
3755
3756 static void
3757 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
3758 {
3759   gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
3760   gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
3761
3762   gfc_conv_tmp_array_ref (se);
3763   gfc_advance_se_ss_chain (se);
3764 }
3765
3766
3767 /* Build a static initializer.  EXPR is the expression for the initial value.
3768    The other parameters describe the variable of the component being 
3769    initialized. EXPR may be null.  */
3770
3771 tree
3772 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
3773                       bool array, bool pointer)
3774 {
3775   gfc_se se;
3776
3777   if (!(expr || pointer))
3778     return NULL_TREE;
3779
3780   /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
3781      (these are the only two iso_c_binding derived types that can be
3782      used as initialization expressions).  If so, we need to modify
3783      the 'expr' to be that for a (void *).  */
3784   if (expr != NULL && expr->ts.type == BT_DERIVED
3785       && expr->ts.is_iso_c && expr->ts.u.derived)
3786     {
3787       gfc_symbol *derived = expr->ts.u.derived;
3788
3789       expr = gfc_int_expr (0);
3790
3791       /* The derived symbol has already been converted to a (void *).  Use
3792          its kind.  */
3793       expr->ts.f90_type = derived->ts.f90_type;
3794       expr->ts.kind = derived->ts.kind;
3795     }
3796   
3797   if (array)
3798     {
3799       /* Arrays need special handling.  */
3800       if (pointer)
3801         return gfc_build_null_descriptor (type);
3802       else
3803         return gfc_conv_array_initializer (type, expr);
3804     }
3805   else if (pointer)
3806     return fold_convert (type, null_pointer_node);
3807   else
3808     {
3809       switch (ts->type)
3810         {
3811         case BT_DERIVED:
3812         case BT_CLASS:
3813           gfc_init_se (&se, NULL);
3814           gfc_conv_structure (&se, expr, 1);
3815           return se.expr;
3816
3817         case BT_CHARACTER:
3818           return gfc_conv_string_init (ts->u.cl->backend_decl,expr);
3819
3820         default:
3821           gfc_init_se (&se, NULL);
3822           gfc_conv_constant (&se, expr);
3823           return se.expr;
3824         }
3825     }
3826 }
3827   
3828 static tree
3829 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3830 {
3831   gfc_se rse;
3832   gfc_se lse;
3833   gfc_ss *rss;
3834   gfc_ss *lss;
3835   stmtblock_t body;
3836   stmtblock_t block;
3837   gfc_loopinfo loop;
3838   int n;
3839   tree tmp;
3840
3841   gfc_start_block (&block);
3842
3843   /* Initialize the scalarizer.  */
3844   gfc_init_loopinfo (&loop);
3845
3846   gfc_init_se (&lse, NULL);
3847   gfc_init_se (&rse, NULL);
3848
3849   /* Walk the rhs.  */
3850   rss = gfc_walk_expr (expr);
3851   if (rss == gfc_ss_terminator)
3852     {
3853       /* The rhs is scalar.  Add a ss for the expression.  */
3854       rss = gfc_get_ss ();
3855       rss->next = gfc_ss_terminator;
3856       rss->type = GFC_SS_SCALAR;
3857       rss->expr = expr;
3858     }
3859
3860   /* Create a SS for the destination.  */
3861   lss = gfc_get_ss ();
3862   lss->type = GFC_SS_COMPONENT;
3863   lss->expr = NULL;
3864   lss->shape = gfc_get_shape (cm->as->rank);
3865   lss->next = gfc_ss_terminator;
3866   lss->data.info.dimen = cm->as->rank;
3867   lss->data.info.descriptor = dest;
3868   lss->data.info.data = gfc_conv_array_data (dest);
3869   lss->data.info.offset = gfc_conv_array_offset (dest);
3870   for (n = 0; n < cm->as->rank; n++)
3871     {
3872       lss->data.info.dim[n] = n;
3873       lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
3874       lss->data.info.stride[n] = gfc_index_one_node;
3875
3876       mpz_init (lss->shape[n]);
3877       mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
3878                cm->as->lower[n]->value.integer);
3879       mpz_add_ui (lss->shape[n], lss->shape[n], 1);
3880     }
3881   
3882   /* Associate the SS with the loop.  */
3883   gfc_add_ss_to_loop (&loop, lss);
3884   gfc_add_ss_to_loop (&loop, rss);
3885
3886   /* Calculate the bounds of the scalarization.  */
3887   gfc_conv_ss_startstride (&loop);
3888
3889   /* Setup the scalarizing loops.  */
3890   gfc_conv_loop_setup (&loop, &expr->where);
3891
3892   /* Setup the gfc_se structures.  */
3893   gfc_copy_loopinfo_to_se (&lse, &loop);
3894   gfc_copy_loopinfo_to_se (&rse, &loop);
3895
3896   rse.ss = rss;
3897   gfc_mark_ss_chain_used (rss, 1);
3898   lse.ss = lss;
3899   gfc_mark_ss_chain_used (lss, 1);
3900
3901   /* Start the scalarized loop body.  */
3902   gfc_start_scalarized_body (&loop, &body);
3903
3904   gfc_conv_tmp_array_ref (&lse);
3905   if (cm->ts.type == BT_CHARACTER)
3906     lse.string_length = cm->ts.u.cl->backend_decl;
3907
3908   gfc_conv_expr (&rse, expr);
3909
3910   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
3911   gfc_add_expr_to_block (&body, tmp);
3912
3913   gcc_assert (rse.ss == gfc_ss_terminator);
3914
3915   /* Generate the copying loops.  */
3916   gfc_trans_scalarizing_loops (&loop, &body);
3917
3918   /* Wrap the whole thing up.  */
3919   gfc_add_block_to_block (&block, &loop.pre);
3920   gfc_add_block_to_block (&block, &loop.post);
3921
3922   for (n = 0; n < cm->as->rank; n++)
3923     mpz_clear (lss->shape[n]);
3924   gfc_free (lss->shape);
3925
3926   gfc_cleanup_loop (&loop);
3927
3928   return gfc_finish_block (&block);
3929 }
3930
3931
3932 /* Assign a single component of a derived type constructor.  */
3933
3934 static tree
3935 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3936 {
3937   gfc_se se;
3938   gfc_se lse;
3939   gfc_ss *rss;
3940   stmtblock_t block;
3941   tree tmp;
3942   tree offset;
3943   int n;
3944
3945   gfc_start_block (&block);
3946
3947   if (cm->attr.pointer)
3948     {
3949       gfc_init_se (&se, NULL);
3950       /* Pointer component.  */
3951       if (cm->attr.dimension)
3952         {
3953           /* Array pointer.  */
3954           if (expr->expr_type == EXPR_NULL)
3955             gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
3956           else
3957             {
3958               rss = gfc_walk_expr (expr);
3959               se.direct_byref = 1;
3960               se.expr = dest;
3961               gfc_conv_expr_descriptor (&se, expr, rss);
3962               gfc_add_block_to_block (&block, &se.pre);
3963               gfc_add_block_to_block (&block, &se.post);
3964             }
3965         }
3966       else
3967         {
3968           /* Scalar pointers.  */
3969           se.want_pointer = 1;
3970           gfc_conv_expr (&se, expr);
3971           gfc_add_block_to_block (&block, &se.pre);
3972           gfc_add_modify (&block, dest,
3973                                fold_convert (TREE_TYPE (dest), se.expr));
3974           gfc_add_block_to_block (&block, &se.post);
3975         }
3976     }
3977   else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
3978     {
3979       /* NULL initialization for CLASS components.  */
3980       tmp = gfc_trans_structure_assign (dest,
3981                                         gfc_default_initializer (&cm->ts));
3982       gfc_add_expr_to_block (&block, tmp);
3983     }
3984   else if (cm->attr.dimension)
3985     {
3986       if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
3987         gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
3988       else if (cm->attr.allocatable)
3989         {
3990           tree tmp2;
3991
3992           gfc_init_se (&se, NULL);
3993  
3994           rss = gfc_walk_expr (expr);
3995           se.want_pointer = 0;
3996           gfc_conv_expr_descriptor (&se, expr, rss);
3997           gfc_add_block_to_block (&block, &se.pre);
3998           gfc_add_modify (&block, dest, se.expr);
3999
4000           if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
4001             tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr, dest,
4002                                        cm->as->rank);
4003           else
4004             tmp = gfc_duplicate_allocatable (dest, se.expr,
4005                                              TREE_TYPE(cm->backend_decl),
4006                                              cm->as->rank);
4007
4008           gfc_add_expr_to_block (&block, tmp);
4009           gfc_add_block_to_block (&block, &se.post);
4010
4011           if (expr->expr_type != EXPR_VARIABLE)
4012             gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
4013
4014           /* Shift the lbound and ubound of temporaries to being unity, rather
4015              than zero, based.  Calculate the offset for all cases.  */
4016           offset = gfc_conv_descriptor_offset_get (dest);
4017           gfc_add_modify (&block, offset, gfc_index_zero_node);
4018           tmp2 =gfc_create_var (gfc_array_index_type, NULL);
4019           for (n = 0; n < expr->rank; n++)
4020             {
4021               if (expr->expr_type != EXPR_VARIABLE
4022                     && expr->expr_type != EXPR_CONSTANT)
4023                 {
4024                   tree span;
4025                   tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
4026                   span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
4027                             gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
4028                   tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4029                                      span, gfc_index_one_node);
4030                   gfc_conv_descriptor_ubound_set (&block, dest, gfc_rank_cst[n],
4031                                                   tmp);
4032                   gfc_conv_descriptor_lbound_set (&block, dest, gfc_rank_cst[n],
4033                                                   gfc_index_one_node);
4034                 }
4035               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4036                                  gfc_conv_descriptor_lbound_get (dest,
4037                                                              gfc_rank_cst[n]),
4038                                  gfc_conv_descriptor_stride_get (dest,
4039                                                              gfc_rank_cst[n]));
4040               gfc_add_modify (&block, tmp2, tmp);
4041               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
4042               gfc_conv_descriptor_offset_set (&block, dest, tmp);
4043             }
4044
4045           if (expr->expr_type == EXPR_FUNCTION
4046                 && expr->value.function.isym
4047                 && expr->value.function.isym->conversion
4048                 && expr->value.function.actual->expr
4049                 && expr->value.function.actual->expr->expr_type
4050                                                 == EXPR_VARIABLE)
4051             {
4052               /* If a conversion expression has a null data pointer
4053                  argument, nullify the allocatable component.  */
4054               gfc_symbol *s;
4055               tree non_null_expr;
4056               tree null_expr;
4057               s = expr->value.function.actual->expr->symtree->n.sym;
4058               if (s->attr.allocatable || s->attr.pointer)
4059                 {
4060                   non_null_expr = gfc_finish_block (&block);
4061                   gfc_start_block (&block);
4062                   gfc_conv_descriptor_data_set (&block, dest,
4063                                                 null_pointer_node);
4064                   null_expr = gfc_finish_block (&block);
4065                   tmp = gfc_conv_descriptor_data_get (s->backend_decl);
4066                   tmp = build2 (EQ_EXPR, boolean_type_node, tmp,
4067                                 fold_convert (TREE_TYPE (tmp),
4068                                               null_pointer_node));
4069                   return build3_v (COND_EXPR, tmp, null_expr,
4070                                    non_null_expr);
4071                 }
4072             }
4073         }
4074       else
4075         {
4076           tmp = gfc_trans_subarray_assign (dest, cm, expr);
4077           gfc_add_expr_to_block (&block, tmp);
4078         }
4079     }
4080   else if (expr->ts.type == BT_DERIVED)
4081     {
4082       if (expr->expr_type != EXPR_STRUCTURE)
4083         {
4084           gfc_init_se (&se, NULL);
4085           gfc_conv_expr (&se, expr);
4086           gfc_add_block_to_block (&block, &se.pre);
4087           gfc_add_modify (&block, dest,
4088                                fold_convert (TREE_TYPE (dest), se.expr));
4089           gfc_add_block_to_block (&block, &se.post);
4090         }
4091       else
4092         {
4093           /* Nested constructors.  */
4094           tmp = gfc_trans_structure_assign (dest, expr);
4095           gfc_add_expr_to_block (&block, tmp);
4096         }
4097     }
4098   else
4099     {
4100       /* Scalar component.  */
4101       gfc_init_se (&se, NULL);
4102       gfc_init_se (&lse, NULL);
4103
4104       gfc_conv_expr (&se, expr);
4105       if (cm->ts.type == BT_CHARACTER)
4106         lse.string_length = cm->ts.u.cl->backend_decl;
4107       lse.expr = dest;
4108       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
4109       gfc_add_expr_to_block (&block, tmp);
4110     }
4111   return gfc_finish_block (&block);
4112 }
4113
4114 /* Assign a derived type constructor to a variable.  */
4115
4116 static tree
4117 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
4118 {
4119   gfc_constructor *c;
4120   gfc_component *cm;
4121   stmtblock_t block;
4122   tree field;
4123   tree tmp;
4124
4125   gfc_start_block (&block);
4126   cm = expr->ts.u.derived->components;
4127   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
4128     {
4129       /* Skip absent members in default initializers.  */
4130       if (!c->expr)
4131         continue;
4132
4133       field = cm->backend_decl;
4134       tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field),
4135                          dest, field, NULL_TREE);
4136       tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
4137       gfc_add_expr_to_block (&block, tmp);
4138     }
4139   return gfc_finish_block (&block);
4140 }
4141
4142 /* Build an expression for a constructor. If init is nonzero then
4143    this is part of a static variable initializer.  */
4144
4145 void
4146 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
4147 {
4148   gfc_constructor *c;
4149   gfc_component *cm;
4150   tree val;
4151   tree type;
4152   tree tmp;
4153   VEC(constructor_elt,gc) *v = NULL;
4154
4155   gcc_assert (se->ss == NULL);
4156   gcc_assert (expr->expr_type == EXPR_STRUCTURE);
4157   type = gfc_typenode_for_spec (&expr->ts);
4158
4159   if (!init)
4160     {
4161       /* Create a temporary variable and fill it in.  */
4162       se->expr = gfc_create_var (type, expr->ts.u.derived->name);
4163       tmp = gfc_trans_structure_assign (se->expr, expr);
4164       gfc_add_expr_to_block (&se->pre, tmp);
4165       return;
4166     }
4167
4168   cm = expr->ts.u.derived->components;
4169
4170   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
4171     {
4172       /* Skip absent members in default initializers and allocatable
4173          components.  Although the latter have a default initializer
4174          of EXPR_NULL,... by default, the static nullify is not needed
4175          since this is done every time we come into scope.  */
4176       if (!c->expr || cm->attr.allocatable)
4177         continue;
4178
4179       if (cm->ts.type == BT_CLASS)
4180         {
4181           val = gfc_conv_initializer (c->expr, &cm->ts,
4182               TREE_TYPE (cm->ts.u.derived->components->backend_decl),
4183               cm->ts.u.derived->components->attr.dimension,
4184               cm->ts.u.derived->components->attr.pointer);
4185
4186           /* Append it to the constructor list.  */
4187           CONSTRUCTOR_APPEND_ELT (v, cm->ts.u.derived->components->backend_decl,
4188                                   val);
4189         }
4190       else
4191         {
4192           val = gfc_conv_initializer (c->expr, &cm->ts,
4193               TREE_TYPE (cm->backend_decl), cm->attr.dimension,
4194               cm->attr.pointer || cm->attr.proc_pointer);
4195
4196           /* Append it to the constructor list.  */
4197           CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
4198         }
4199     }
4200   se->expr = build_constructor (type, v);
4201   if (init) 
4202     TREE_CONSTANT (se->expr) = 1;
4203 }
4204
4205
4206 /* Translate a substring expression.  */
4207
4208 static void
4209 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
4210 {
4211   gfc_ref *ref;
4212
4213   ref = expr->ref;
4214
4215   gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
4216
4217   se->expr = gfc_build_wide_string_const (expr->ts.kind,
4218                                           expr->value.character.length,
4219                                           expr->value.character.string);
4220
4221   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
4222   TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
4223
4224   if (ref)
4225     gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
4226 }
4227
4228
4229 /* Entry point for expression translation.  Evaluates a scalar quantity.
4230    EXPR is the expression to be translated, and SE is the state structure if
4231    called from within the scalarized.  */
4232
4233 void
4234 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
4235 {
4236   if (se->ss && se->ss->expr == expr
4237       && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
4238     {
4239       /* Substitute a scalar expression evaluated outside the scalarization
4240          loop.  */
4241       se->expr = se->ss->data.scalar.expr;
4242       se->string_length = se->ss->string_length;
4243       gfc_advance_se_ss_chain (se);
4244       return;
4245     }
4246
4247   /* We need to convert the expressions for the iso_c_binding derived types.
4248      C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
4249      null_pointer_node.  C_PTR and C_FUNPTR are converted to match the
4250      typespec for the C_PTR and C_FUNPTR symbols, which has already been
4251      updated to be an integer with a kind equal to the size of a (void *).  */
4252   if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
4253       && expr->ts.u.derived->attr.is_iso_c)
4254     {
4255       if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
4256           || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
4257         {
4258           /* Set expr_type to EXPR_NULL, which will result in
4259              null_pointer_node being used below.  */
4260           expr->expr_type = EXPR_NULL;
4261         }
4262       else
4263         {
4264           /* Update the type/kind of the expression to be what the new
4265              type/kind are for the updated symbols of C_PTR/C_FUNPTR.  */
4266           expr->ts.type = expr->ts.u.derived->ts.type;
4267           expr->ts.f90_type = expr->ts.u.derived->ts.f90_type;
4268           expr->ts.kind = expr->ts.u.derived->ts.kind;
4269         }
4270     }
4271   
4272   switch (expr->expr_type)
4273     {
4274     case EXPR_OP:
4275       gfc_conv_expr_op (se, expr);
4276       break;
4277
4278     case EXPR_FUNCTION:
4279       gfc_conv_function_expr (se, expr);
4280       break;
4281
4282     case EXPR_CONSTANT:
4283       gfc_conv_constant (se, expr);
4284       break;
4285
4286     case EXPR_VARIABLE:
4287       gfc_conv_variable (se, expr);
4288       break;
4289
4290     case EXPR_NULL:
4291       se->expr = null_pointer_node;
4292       break;
4293
4294     case EXPR_SUBSTRING:
4295       gfc_conv_substring_expr (se, expr);
4296       break;
4297
4298     case EXPR_STRUCTURE:
4299       gfc_conv_structure (se, expr, 0);
4300       break;
4301
4302     case EXPR_ARRAY:
4303       gfc_conv_array_constructor_expr (se, expr);
4304       break;
4305
4306     default:
4307       gcc_unreachable ();
4308       break;
4309     }
4310 }
4311
4312 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
4313    of an assignment.  */
4314 void
4315 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
4316 {
4317   gfc_conv_expr (se, expr);
4318   /* All numeric lvalues should have empty post chains.  If not we need to
4319      figure out a way of rewriting an lvalue so that it has no post chain.  */
4320   gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
4321 }
4322
4323 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
4324    numeric expressions.  Used for scalar values where inserting cleanup code
4325    is inconvenient.  */
4326 void
4327 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
4328 {
4329   tree val;
4330
4331   gcc_assert (expr->ts.type != BT_CHARACTER);
4332   gfc_conv_expr (se, expr);
4333   if (se->post.head)
4334     {
4335       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
4336       gfc_add_modify (&se->pre, val, se->expr);
4337       se->expr = val;
4338       gfc_add_block_to_block (&se->pre, &se->post);
4339     }
4340 }
4341
4342 /* Helper to translate an expression and convert it to a particular type.  */
4343 void
4344 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
4345 {
4346   gfc_conv_expr_val (se, expr);
4347   se->expr = convert (type, se->expr);
4348 }
4349
4350
4351 /* Converts an expression so that it can be passed by reference.  Scalar
4352    values only.  */
4353
4354 void
4355 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
4356 {
4357   tree var;
4358
4359   if (se->ss && se->ss->expr == expr
4360       && se->ss->type == GFC_SS_REFERENCE)
4361     {
4362       se->expr = se->ss->data.scalar.expr;
4363       se->string_length = se->ss->string_length;
4364       gfc_advance_se_ss_chain (se);
4365       return;
4366     }
4367
4368   if (expr->ts.type == BT_CHARACTER)
4369     {
4370       gfc_conv_expr (se, expr);
4371       gfc_conv_string_parameter (se);
4372       return;
4373     }
4374
4375   if (expr->expr_type == EXPR_VARIABLE)
4376     {
4377       se->want_pointer = 1;
4378       gfc_conv_expr (se, expr);
4379       if (se->post.head)
4380         {
4381           var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4382           gfc_add_modify (&se->pre, var, se->expr);
4383           gfc_add_block_to_block (&se->pre, &se->post);
4384           se->expr = var;
4385         }
4386       return;
4387     }
4388
4389   if (expr->expr_type == EXPR_FUNCTION
4390       && ((expr->value.function.esym
4391            && expr->value.function.esym->result->attr.pointer
4392            && !expr->value.function.esym->result->attr.dimension)
4393           || (!expr->value.function.esym
4394               && expr->symtree->n.sym->attr.pointer
4395               && !expr->symtree->n.sym->attr.dimension)))
4396     {
4397       se->want_pointer = 1;
4398       gfc_conv_expr (se, expr);
4399       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4400       gfc_add_modify (&se->pre, var, se->expr);
4401       se->expr = var;
4402       return;
4403     }
4404
4405
4406   gfc_conv_expr (se, expr);
4407
4408   /* Create a temporary var to hold the value.  */
4409   if (TREE_CONSTANT (se->expr))
4410     {
4411       tree tmp = se->expr;
4412       STRIP_TYPE_NOPS (tmp);
4413       var = build_decl (input_location,
4414                         CONST_DECL, NULL, TREE_TYPE (tmp));
4415       DECL_INITIAL (var) = tmp;
4416       TREE_STATIC (var) = 1;
4417       pushdecl (var);
4418     }
4419   else
4420     {
4421       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4422       gfc_add_modify (&se->pre, var, se->expr);
4423     }
4424   gfc_add_block_to_block (&se->pre, &se->post);
4425
4426   /* Take the address of that value.  */
4427   se->expr = gfc_build_addr_expr (NULL_TREE, var);
4428 }
4429
4430
4431 tree
4432 gfc_trans_pointer_assign (gfc_code * code)
4433 {
4434   return gfc_trans_pointer_assignment (code->expr1, code->expr2);
4435 }
4436
4437
4438 /* Generate code for a pointer assignment.  */
4439
4440 tree
4441 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
4442 {
4443   gfc_se lse;
4444   gfc_se rse;
4445   gfc_ss *lss;
4446   gfc_ss *rss;
4447   stmtblock_t block;
4448   tree desc;
4449   tree tmp;
4450   tree decl;
4451
4452   gfc_start_block (&block);
4453
4454   gfc_init_se (&lse, NULL);
4455
4456   lss = gfc_walk_expr (expr1);
4457   rss = gfc_walk_expr (expr2);
4458   if (lss == gfc_ss_terminator)
4459     {
4460       /* Scalar pointers.  */
4461       lse.want_pointer = 1;
4462       gfc_conv_expr (&lse, expr1);
4463       gcc_assert (rss == gfc_ss_terminator);
4464       gfc_init_se (&rse, NULL);
4465       rse.want_pointer = 1;
4466       gfc_conv_expr (&rse, expr2);
4467
4468       if (expr1->symtree->n.sym->attr.proc_pointer
4469           && expr1->symtree->n.sym->attr.dummy)
4470         lse.expr = build_fold_indirect_ref_loc (input_location,
4471                                             lse.expr);
4472
4473       if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
4474           && expr2->symtree->n.sym->attr.dummy)
4475         rse.expr = build_fold_indirect_ref_loc (input_location,
4476                                             rse.expr);
4477
4478       gfc_add_block_to_block (&block, &lse.pre);
4479       gfc_add_block_to_block (&block, &rse.pre);
4480
4481       /* Check character lengths if character expression.  The test is only
4482          really added if -fbounds-check is enabled.  */
4483       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
4484           && !expr1->symtree->n.sym->attr.proc_pointer
4485           && !gfc_is_proc_ptr_comp (expr1, NULL))
4486         {
4487           gcc_assert (expr2->ts.type == BT_CHARACTER);
4488           gcc_assert (lse.string_length && rse.string_length);
4489           gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4490                                        lse.string_length, rse.string_length,
4491                                        &block);
4492         }
4493
4494       gfc_add_modify (&block, lse.expr,
4495                            fold_convert (TREE_TYPE (lse.expr), rse.expr));
4496
4497       gfc_add_block_to_block (&block, &rse.post);
4498       gfc_add_block_to_block (&block, &lse.post);
4499     }
4500   else
4501     {
4502       tree strlen_lhs;
4503       tree strlen_rhs = NULL_TREE;
4504
4505       /* Array pointer.  */
4506       gfc_conv_expr_descriptor (&lse, expr1, lss);
4507       strlen_lhs = lse.string_length;
4508       switch (expr2->expr_type)
4509         {
4510         case EXPR_NULL:
4511           /* Just set the data pointer to null.  */
4512           gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
4513           break;
4514
4515         case EXPR_VARIABLE:
4516           /* Assign directly to the pointer's descriptor.  */
4517           lse.direct_byref = 1;
4518           gfc_conv_expr_descriptor (&lse, expr2, rss);
4519           strlen_rhs = lse.string_length;
4520
4521           /* If this is a subreference array pointer assignment, use the rhs
4522              descriptor element size for the lhs span.  */
4523           if (expr1->symtree->n.sym->attr.subref_array_pointer)
4524             {
4525               decl = expr1->symtree->n.sym->backend_decl;
4526               gfc_init_se (&rse, NULL);
4527               rse.descriptor_only = 1;
4528               gfc_conv_expr (&rse, expr2);
4529               tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
4530               tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
4531               if (!INTEGER_CST_P (tmp))
4532                 gfc_add_block_to_block (&lse.post, &rse.pre);
4533               gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
4534             }
4535
4536           break;
4537
4538         default:
4539           /* Assign to a temporary descriptor and then copy that
4540              temporary to the pointer.  */
4541           desc = lse.expr;
4542           tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
4543
4544           lse.expr = tmp;
4545           lse.direct_byref = 1;
4546           gfc_conv_expr_descriptor (&lse, expr2, rss);
4547           strlen_rhs = lse.string_length;
4548           gfc_add_modify (&lse.pre, desc, tmp);
4549           break;
4550         }
4551
4552       gfc_add_block_to_block (&block, &lse.pre);
4553
4554       /* Check string lengths if applicable.  The check is only really added
4555          to the output code if -fbounds-check is enabled.  */
4556       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
4557         {
4558           gcc_assert (expr2->ts.type == BT_CHARACTER);
4559           gcc_assert (strlen_lhs && strlen_rhs);
4560           gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4561                                        strlen_lhs, strlen_rhs, &block);
4562         }
4563
4564       gfc_add_block_to_block (&block, &lse.post);
4565     }
4566   return gfc_finish_block (&block);
4567 }
4568
4569
4570 /* Makes sure se is suitable for passing as a function string parameter.  */
4571 /* TODO: Need to check all callers of this function.  It may be abused.  */
4572
4573 void
4574 gfc_conv_string_parameter (gfc_se * se)
4575 {
4576   tree type;
4577
4578   if (TREE_CODE (se->expr) == STRING_CST)
4579     {
4580       type = TREE_TYPE (TREE_TYPE (se->expr));
4581       se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4582       return;
4583     }
4584
4585   if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
4586     {
4587       if (TREE_CODE (se->expr) != INDIRECT_REF)
4588         {
4589           type = TREE_TYPE (se->expr);
4590           se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4591         }
4592       else
4593         {
4594           type = gfc_get_character_type_len (gfc_default_character_kind,
4595                                              se->string_length);
4596           type = build_pointer_type (type);
4597           se->expr = gfc_build_addr_expr (type, se->expr);
4598         }
4599     }
4600
4601   gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
4602   gcc_assert (se->string_length
4603           && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
4604 }
4605
4606
4607 /* Generate code for assignment of scalar variables.  Includes character
4608    strings and derived types with allocatable components.  */
4609
4610 tree
4611 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
4612                          bool l_is_temp, bool r_is_var)
4613 {
4614   stmtblock_t block;
4615   tree tmp;
4616   tree cond;
4617
4618   gfc_init_block (&block);
4619
4620   if (ts.type == BT_CHARACTER)
4621     {
4622       tree rlen = NULL;
4623       tree llen = NULL;
4624
4625       if (lse->string_length != NULL_TREE)
4626         {
4627           gfc_conv_string_parameter (lse);
4628           gfc_add_block_to_block (&block, &lse->pre);
4629           llen = lse->string_length;
4630         }
4631
4632       if (rse->string_length != NULL_TREE)
4633         {
4634           gcc_assert (rse->string_length != NULL_TREE);
4635           gfc_conv_string_parameter (rse);
4636           gfc_add_block_to_block (&block, &rse->pre);
4637           rlen = rse->string_length;
4638         }
4639
4640       gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
4641                              rse->expr, ts.kind);
4642     }
4643   else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
4644     {
4645       cond = NULL_TREE;
4646         
4647       /* Are the rhs and the lhs the same?  */
4648       if (r_is_var)
4649         {
4650           cond = fold_build2 (EQ_EXPR, boolean_type_node,
4651                               gfc_build_addr_expr (NULL_TREE, lse->expr),
4652                               gfc_build_addr_expr (NULL_TREE, rse->expr));
4653           cond = gfc_evaluate_now (cond, &lse->pre);
4654         }
4655
4656       /* Deallocate the lhs allocated components as long as it is not
4657          the same as the rhs.  This must be done following the assignment
4658          to prevent deallocating data that could be used in the rhs
4659          expression.  */
4660       if (!l_is_temp)
4661         {
4662           tmp = gfc_evaluate_now (lse->expr, &lse->pre);
4663           tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
4664           if (r_is_var)
4665             tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4666                             tmp);
4667           gfc_add_expr_to_block (&lse->post, tmp);
4668         }
4669
4670       gfc_add_block_to_block (&block, &rse->pre);
4671       gfc_add_block_to_block (&block, &lse->pre);
4672
4673       gfc_add_modify (&block, lse->expr,
4674                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
4675
4676       /* Do a deep copy if the rhs is a variable, if it is not the
4677          same as the lhs.  */
4678       if (r_is_var)
4679         {
4680           tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
4681           tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4682                           tmp);
4683           gfc_add_expr_to_block (&block, tmp);
4684         }
4685     }
4686   else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
4687     {
4688       gfc_add_block_to_block (&block, &lse->pre);
4689       gfc_add_block_to_block (&block, &rse->pre);
4690       tmp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lse->expr), rse->expr);
4691       gfc_add_modify (&block, lse->expr, tmp);
4692     }
4693   else
4694     {
4695       gfc_add_block_to_block (&block, &lse->pre);
4696       gfc_add_block_to_block (&block, &rse->pre);
4697
4698       gfc_add_modify (&block, lse->expr,
4699                       fold_convert (TREE_TYPE (lse->expr), rse->expr));
4700     }
4701
4702   gfc_add_block_to_block (&block, &lse->post);
4703   gfc_add_block_to_block (&block, &rse->post);
4704
4705   return gfc_finish_block (&block);
4706 }
4707
4708
4709 /* Try to translate array(:) = func (...), where func is a transformational
4710    array function, without using a temporary.  Returns NULL is this isn't the
4711    case.  */
4712
4713 static tree
4714 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
4715 {
4716   gfc_se se;
4717   gfc_ss *ss;
4718   gfc_ref * ref;
4719   bool seen_array_ref;
4720   bool c = false;
4721   gfc_component *comp = NULL;
4722
4723   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
4724   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
4725     return NULL;
4726
4727   /* Elemental functions don't need a temporary anyway.  */
4728   if (expr2->value.function.esym != NULL
4729       && expr2->value.function.esym->attr.elemental)
4730     return NULL;
4731
4732   /* Fail if rhs is not FULL or a contiguous section.  */
4733   if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
4734     return NULL;
4735
4736   /* Fail if EXPR1 can't be expressed as a descriptor.  */
4737   if (gfc_ref_needs_temporary_p (expr1->ref))
4738     return NULL;
4739
4740   /* Functions returning pointers need temporaries.  */
4741   if (expr2->symtree->n.sym->attr.pointer 
4742       || expr2->symtree->n.sym->attr.allocatable)
4743     return NULL;
4744
4745   /* Character array functions need temporaries unless the
4746      character lengths are the same.  */
4747   if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
4748     {
4749       if (expr1->ts.u.cl->length == NULL
4750             || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
4751         return NULL;
4752
4753       if (expr2->ts.u.cl->length == NULL
4754             || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
4755         return NULL;
4756
4757       if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
4758                      expr2->ts.u.cl->length->value.integer) != 0)
4759         return NULL;
4760     }
4761
4762   /* Check that no LHS component references appear during an array
4763      reference. This is needed because we do not have the means to
4764      span any arbitrary stride with an array descriptor. This check
4765      is not needed for the rhs because the function result has to be
4766      a complete type.  */
4767   seen_array_ref = false;
4768   for (ref = expr1->ref; ref; ref = ref->next)
4769     {
4770       if (ref->type == REF_ARRAY)
4771         seen_array_ref= true;
4772       else if (ref->type == REF_COMPONENT && seen_array_ref)
4773         return NULL;
4774     }
4775
4776   /* Check for a dependency.  */
4777   if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
4778                                    expr2->value.function.esym,
4779                                    expr2->value.function.actual,
4780                                    NOT_ELEMENTAL))
4781     return NULL;
4782
4783   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
4784      functions.  */
4785   gcc_assert (expr2->value.function.isym
4786               || (gfc_is_proc_ptr_comp (expr2, &comp)
4787                   && comp && comp->attr.dimension)
4788               || (!comp && gfc_return_by_reference (expr2->value.function.esym)
4789                   && expr2->value.function.esym->result->attr.dimension));
4790
4791   ss = gfc_walk_expr (expr1);
4792   gcc_assert (ss != gfc_ss_terminator);
4793   gfc_init_se (&se, NULL);
4794   gfc_start_block (&se.pre);
4795   se.want_pointer = 1;
4796
4797   gfc_conv_array_parameter (&se, expr1, ss, 0, NULL, NULL, NULL);
4798
4799   se.direct_byref = 1;
4800   se.ss = gfc_walk_expr (expr2);
4801   gcc_assert (se.ss != gfc_ss_terminator);
4802   gfc_conv_function_expr (&se, expr2);
4803   gfc_add_block_to_block (&se.pre, &se.post);
4804
4805   return gfc_finish_block (&se.pre);
4806 }
4807
4808 /* Determine whether the given EXPR_CONSTANT is a zero initializer.  */
4809
4810 static bool
4811 is_zero_initializer_p (gfc_expr * expr)
4812 {
4813   if (expr->expr_type != EXPR_CONSTANT)
4814     return false;
4815
4816   /* We ignore constants with prescribed memory representations for now.  */
4817   if (expr->representation.string)
4818     return false;
4819
4820   switch (expr->ts.type)
4821     {
4822     case BT_INTEGER:
4823       return mpz_cmp_si (expr->value.integer, 0) == 0;
4824
4825     case BT_REAL:
4826       return mpfr_zero_p (expr->value.real)
4827              && MPFR_SIGN (expr->value.real) >= 0;
4828
4829     case BT_LOGICAL:
4830       return expr->value.logical == 0;
4831
4832     case BT_COMPLEX:
4833       return mpfr_zero_p (mpc_realref (expr->value.complex))
4834              && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
4835              && mpfr_zero_p (mpc_imagref (expr->value.complex))
4836              && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
4837
4838     default:
4839       break;
4840     }
4841   return false;
4842 }
4843
4844 /* Try to efficiently translate array(:) = 0.  Return NULL if this
4845    can't be done.  */
4846
4847 static tree
4848 gfc_trans_zero_assign (gfc_expr * expr)
4849 {
4850   tree dest, len, type;
4851   tree tmp;
4852   gfc_symbol *sym;
4853
4854   sym = expr->symtree->n.sym;
4855   dest = gfc_get_symbol_decl (sym);
4856
4857   type = TREE_TYPE (dest);
4858   if (POINTER_TYPE_P (type))
4859     type = TREE_TYPE (type);
4860   if (!GFC_ARRAY_TYPE_P (type))
4861     return NULL_TREE;
4862
4863   /* Determine the length of the array.  */
4864   len = GFC_TYPE_ARRAY_SIZE (type);
4865   if (!len || TREE_CODE (len) != INTEGER_CST)
4866     return NULL_TREE;
4867
4868   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
4869   len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
4870                      fold_convert (gfc_array_index_type, tmp));
4871
4872   /* If we are zeroing a local array avoid taking its address by emitting
4873      a = {} instead.  */
4874   if (!POINTER_TYPE_P (TREE_TYPE (dest)))
4875     return build2 (MODIFY_EXPR, void_type_node,
4876                    dest, build_constructor (TREE_TYPE (dest), NULL));
4877
4878   /* Convert arguments to the correct types.  */
4879   dest = fold_convert (pvoid_type_node, dest);
4880   len = fold_convert (size_type_node, len);
4881
4882   /* Construct call to __builtin_memset.  */
4883   tmp = build_call_expr_loc (input_location,
4884                          built_in_decls[BUILT_IN_MEMSET],
4885                          3, dest, integer_zero_node, len);
4886   return fold_convert (void_type_node, tmp);
4887 }
4888
4889
4890 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
4891    that constructs the call to __builtin_memcpy.  */
4892
4893 tree
4894 gfc_build_memcpy_call (tree dst, tree src, tree len)
4895 {
4896   tree tmp;
4897
4898   /* Convert arguments to the correct types.  */
4899   if (!POINTER_TYPE_P (TREE_TYPE (dst)))
4900     dst = gfc_build_addr_expr (pvoid_type_node, dst);
4901   else
4902     dst = fold_convert (pvoid_type_node, dst);
4903
4904   if (!POINTER_TYPE_P (TREE_TYPE (src)))
4905     src = gfc_build_addr_expr (pvoid_type_node, src);
4906   else
4907     src = fold_convert (pvoid_type_node, src);
4908
4909   len = fold_convert (size_type_node, len);
4910
4911   /* Construct call to __builtin_memcpy.  */
4912   tmp = build_call_expr_loc (input_location,
4913                          built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
4914   return fold_convert (void_type_node, tmp);
4915 }
4916
4917
4918 /* Try to efficiently translate dst(:) = src(:).  Return NULL if this
4919    can't be done.  EXPR1 is the destination/lhs and EXPR2 is the
4920    source/rhs, both are gfc_full_array_ref_p which have been checked for
4921    dependencies.  */
4922
4923 static tree
4924 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
4925 {
4926   tree dst, dlen, dtype;
4927   tree src, slen, stype;
4928   tree tmp;
4929
4930   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
4931   src = gfc_get_symbol_decl (expr2->symtree->n.sym);
4932
4933   dtype = TREE_TYPE (dst);
4934   if (POINTER_TYPE_P (dtype))
4935     dtype = TREE_TYPE (dtype);
4936   stype = TREE_TYPE (src);
4937   if (POINTER_TYPE_P (stype))
4938     stype = TREE_TYPE (stype);
4939
4940   if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
4941     return NULL_TREE;
4942
4943   /* Determine the lengths of the arrays.  */
4944   dlen = GFC_TYPE_ARRAY_SIZE (dtype);
4945   if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
4946     return NULL_TREE;
4947   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
4948   dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
4949                       fold_convert (gfc_array_index_type, tmp));
4950
4951   slen = GFC_TYPE_ARRAY_SIZE (stype);
4952   if (!slen || TREE_CODE (slen) != INTEGER_CST)
4953     return NULL_TREE;
4954   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
4955   slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
4956                       fold_convert (gfc_array_index_type, tmp));
4957
4958   /* Sanity check that they are the same.  This should always be
4959      the case, as we should already have checked for conformance.  */
4960   if (!tree_int_cst_equal (slen, dlen))
4961     return NULL_TREE;
4962
4963   return gfc_build_memcpy_call (dst, src, dlen);
4964 }
4965
4966
4967 /* Try to efficiently translate array(:) = (/ ... /).  Return NULL if
4968    this can't be done.  EXPR1 is the destination/lhs for which
4969    gfc_full_array_ref_p is true, and EXPR2 is the source/rhs.  */
4970
4971 static tree
4972 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
4973 {
4974   unsigned HOST_WIDE_INT nelem;
4975   tree dst, dtype;
4976   tree src, stype;
4977   tree len;
4978   tree tmp;
4979
4980   nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
4981   if (nelem == 0)
4982     return NULL_TREE;
4983
4984   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
4985   dtype = TREE_TYPE (dst);
4986   if (POINTER_TYPE_P (dtype))
4987     dtype = TREE_TYPE (dtype);
4988   if (!GFC_ARRAY_TYPE_P (dtype))
4989     return NULL_TREE;
4990
4991   /* Determine the lengths of the array.  */
4992   len = GFC_TYPE_ARRAY_SIZE (dtype);
4993   if (!len || TREE_CODE (len) != INTEGER_CST)
4994     return NULL_TREE;
4995
4996   /* Confirm that the constructor is the same size.  */
4997   if (compare_tree_int (len, nelem) != 0)
4998     return NULL_TREE;
4999
5000   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
5001   len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
5002                      fold_convert (gfc_array_index_type, tmp));
5003
5004   stype = gfc_typenode_for_spec (&expr2->ts);
5005   src = gfc_build_constant_array_constructor (expr2, stype);
5006
5007   stype = TREE_TYPE (src);
5008   if (POINTER_TYPE_P (stype))
5009     stype = TREE_TYPE (stype);
5010
5011   return gfc_build_memcpy_call (dst, src, len);
5012 }
5013
5014
5015 /* Subroutine of gfc_trans_assignment that actually scalarizes the
5016    assignment.  EXPR1 is the destination/LHS and EXPR2 is the source/RHS.  */
5017
5018 static tree
5019 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
5020 {
5021   gfc_se lse;
5022   gfc_se rse;
5023   gfc_ss *lss;
5024   gfc_ss *lss_section;
5025   gfc_ss *rss;
5026   gfc_loopinfo loop;
5027   tree tmp;
5028   stmtblock_t block;
5029   stmtblock_t body;
5030   bool l_is_temp;
5031   bool scalar_to_array;
5032   tree string_length;
5033
5034   /* Assignment of the form lhs = rhs.  */
5035   gfc_start_block (&block);
5036
5037   gfc_init_se (&lse, NULL);
5038   gfc_init_se (&rse, NULL);
5039
5040   /* Walk the lhs.  */
5041   lss = gfc_walk_expr (expr1);
5042   rss = NULL;
5043   if (lss != gfc_ss_terminator)
5044     {
5045       /* Allow the scalarizer to workshare array assignments.  */
5046       if (ompws_flags & OMPWS_WORKSHARE_FLAG)
5047         ompws_flags |= OMPWS_SCALARIZER_WS;
5048
5049       /* The assignment needs scalarization.  */
5050       lss_section = lss;
5051
5052       /* Find a non-scalar SS from the lhs.  */
5053       while (lss_section != gfc_ss_terminator
5054              && lss_section->type != GFC_SS_SECTION)
5055         lss_section = lss_section->next;
5056
5057       gcc_assert (lss_section != gfc_ss_terminator);
5058
5059       /* Initialize the scalarizer.  */
5060       gfc_init_loopinfo (&loop);
5061
5062       /* Walk the rhs.  */
5063       rss = gfc_walk_expr (expr2);
5064       if (rss == gfc_ss_terminator)
5065         {
5066           /* The rhs is scalar.  Add a ss for the expression.  */
5067           rss = gfc_get_ss ();
5068           rss->next = gfc_ss_terminator;
5069           rss->type = GFC_SS_SCALAR;
5070           rss->expr = expr2;
5071         }
5072       /* Associate the SS with the loop.  */
5073       gfc_add_ss_to_loop (&loop, lss);
5074       gfc_add_ss_to_loop (&loop, rss);
5075
5076       /* Calculate the bounds of the scalarization.  */
5077       gfc_conv_ss_startstride (&loop);
5078       /* Resolve any data dependencies in the statement.  */
5079       gfc_conv_resolve_dependencies (&loop, lss, rss);
5080       /* Setup the scalarizing loops.  */
5081       gfc_conv_loop_setup (&loop, &expr2->where);
5082
5083       /* Setup the gfc_se structures.  */
5084       gfc_copy_loopinfo_to_se (&lse, &loop);
5085       gfc_copy_loopinfo_to_se (&rse, &loop);
5086
5087       rse.ss = rss;
5088       gfc_mark_ss_chain_used (rss, 1);
5089       if (loop.temp_ss == NULL)
5090         {
5091           lse.ss = lss;
5092           gfc_mark_ss_chain_used (lss, 1);
5093         }
5094       else
5095         {
5096           lse.ss = loop.temp_ss;
5097           gfc_mark_ss_chain_used (lss, 3);
5098           gfc_mark_ss_chain_used (loop.temp_ss, 3);
5099         }
5100
5101       /* Start the scalarized loop body.  */
5102       gfc_start_scalarized_body (&loop, &body);
5103     }
5104   else
5105     gfc_init_block (&body);
5106
5107   l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
5108
5109   /* Translate the expression.  */
5110   gfc_conv_expr (&rse, expr2);
5111
5112   /* Stabilize a string length for temporaries.  */
5113   if (expr2->ts.type == BT_CHARACTER)
5114     string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
5115   else
5116     string_length = NULL_TREE;
5117
5118   if (l_is_temp)
5119     {
5120       gfc_conv_tmp_array_ref (&lse);
5121       gfc_advance_se_ss_chain (&lse);
5122       if (expr2->ts.type == BT_CHARACTER)
5123         lse.string_length = string_length;
5124     }
5125   else
5126     gfc_conv_expr (&lse, expr1);
5127
5128   /* Assignments of scalar derived types with allocatable components
5129      to arrays must be done with a deep copy and the rhs temporary
5130      must have its components deallocated afterwards.  */
5131   scalar_to_array = (expr2->ts.type == BT_DERIVED
5132                        && expr2->ts.u.derived->attr.alloc_comp
5133                        && expr2->expr_type != EXPR_VARIABLE
5134                        && !gfc_is_constant_expr (expr2)
5135                        && expr1->rank && !expr2->rank);
5136   if (scalar_to_array)
5137     {
5138       tmp = gfc_deallocate_alloc_comp (expr2->ts.u.derived, rse.expr, 0);
5139       gfc_add_expr_to_block (&loop.post, tmp);
5140     }
5141
5142   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5143                                  l_is_temp || init_flag,
5144                                  (expr2->expr_type == EXPR_VARIABLE)
5145                                     || scalar_to_array);
5146   gfc_add_expr_to_block (&body, tmp);
5147
5148   if (lss == gfc_ss_terminator)
5149     {
5150       /* Use the scalar assignment as is.  */
5151       gfc_add_block_to_block (&block, &body);
5152     }
5153   else
5154     {
5155       gcc_assert (lse.ss == gfc_ss_terminator
5156                   && rse.ss == gfc_ss_terminator);
5157
5158       if (l_is_temp)
5159         {
5160           gfc_trans_scalarized_loop_boundary (&loop, &body);
5161
5162           /* We need to copy the temporary to the actual lhs.  */
5163           gfc_init_se (&lse, NULL);
5164           gfc_init_se (&rse, NULL);
5165           gfc_copy_loopinfo_to_se (&lse, &loop);
5166           gfc_copy_loopinfo_to_se (&rse, &loop);
5167
5168           rse.ss = loop.temp_ss;
5169           lse.ss = lss;
5170
5171           gfc_conv_tmp_array_ref (&rse);
5172           gfc_advance_se_ss_chain (&rse);
5173           gfc_conv_expr (&lse, expr1);
5174
5175           gcc_assert (lse.ss == gfc_ss_terminator
5176                       && rse.ss == gfc_ss_terminator);
5177
5178           if (expr2->ts.type == BT_CHARACTER)
5179             rse.string_length = string_length;
5180
5181           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5182                                          false, false);
5183           gfc_add_expr_to_block (&body, tmp);
5184         }
5185
5186       /* Generate the copying loops.  */
5187       gfc_trans_scalarizing_loops (&loop, &body);
5188
5189       /* Wrap the whole thing up.  */
5190       gfc_add_block_to_block (&block, &loop.pre);
5191       gfc_add_block_to_block (&block, &loop.post);
5192
5193       gfc_cleanup_loop (&loop);
5194     }
5195
5196   return gfc_finish_block (&block);
5197 }
5198
5199
5200 /* Check whether EXPR is a copyable array.  */
5201
5202 static bool
5203 copyable_array_p (gfc_expr * expr)
5204 {
5205   if (expr->expr_type != EXPR_VARIABLE)
5206     return false;
5207
5208   /* First check it's an array.  */
5209   if (expr->rank < 1 || !expr->ref || expr->ref->next)
5210     return false;
5211
5212   if (!gfc_full_array_ref_p (expr->ref, NULL))
5213     return false;
5214
5215   /* Next check that it's of a simple enough type.  */
5216   switch (expr->ts.type)
5217     {
5218     case BT_INTEGER:
5219     case BT_REAL:
5220     case BT_COMPLEX:
5221     case BT_LOGICAL:
5222       return true;
5223
5224     case BT_CHARACTER:
5225       return false;
5226
5227     case BT_DERIVED:
5228       return !expr->ts.u.derived->attr.alloc_comp;
5229
5230     default:
5231       break;
5232     }
5233
5234   return false;
5235 }
5236
5237 /* Translate an assignment.  */
5238
5239 tree
5240 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
5241 {
5242   tree tmp;
5243
5244   /* Special case a single function returning an array.  */
5245   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5246     {
5247       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5248       if (tmp)
5249         return tmp;
5250     }
5251
5252   /* Special case assigning an array to zero.  */
5253   if (copyable_array_p (expr1)
5254       && is_zero_initializer_p (expr2))
5255     {
5256       tmp = gfc_trans_zero_assign (expr1);
5257       if (tmp)
5258         return tmp;
5259     }
5260
5261   /* Special case copying one array to another.  */
5262   if (copyable_array_p (expr1)
5263       && copyable_array_p (expr2)
5264       && gfc_compare_types (&expr1->ts, &expr2->ts)
5265       && !gfc_check_dependency (expr1, expr2, 0))
5266     {
5267       tmp = gfc_trans_array_copy (expr1, expr2);
5268       if (tmp)
5269         return tmp;
5270     }
5271
5272   /* Special case initializing an array from a constant array constructor.  */
5273   if (copyable_array_p (expr1)
5274       && expr2->expr_type == EXPR_ARRAY
5275       && gfc_compare_types (&expr1->ts, &expr2->ts))
5276     {
5277       tmp = gfc_trans_array_constructor_copy (expr1, expr2);
5278       if (tmp)
5279         return tmp;
5280     }
5281
5282   /* Fallback to the scalarizer to generate explicit loops.  */
5283   return gfc_trans_assignment_1 (expr1, expr2, init_flag);
5284 }
5285
5286 tree
5287 gfc_trans_init_assign (gfc_code * code)
5288 {
5289   return gfc_trans_assignment (code->expr1, code->expr2, true);
5290 }
5291
5292 tree
5293 gfc_trans_assign (gfc_code * code)
5294 {
5295   return gfc_trans_assignment (code->expr1, code->expr2, false);
5296 }
5297
5298
5299 /* Translate an assignment to a CLASS object
5300    (pointer or ordinary assignment).  */
5301
5302 tree
5303 gfc_trans_class_assign (gfc_code *code)
5304 {
5305   stmtblock_t block;
5306   tree tmp;
5307
5308   gfc_start_block (&block);
5309
5310   if (code->expr2->ts.type != BT_CLASS)
5311     {
5312       /* Insert an additional assignment which sets the '$vindex' field.  */
5313       gfc_expr *lhs,*rhs;
5314       lhs = gfc_copy_expr (code->expr1);
5315       gfc_add_component_ref (lhs, "$vindex");
5316       if (code->expr2->ts.type == BT_DERIVED)
5317         /* vindex is constant, determined at compile time.  */
5318         rhs = gfc_int_expr (code->expr2->ts.u.derived->vindex);
5319       else if (code->expr2->expr_type == EXPR_NULL)
5320         rhs = gfc_int_expr (0);
5321       else
5322         gcc_unreachable ();
5323       tmp = gfc_trans_assignment (lhs, rhs, false);
5324       gfc_add_expr_to_block (&block, tmp);
5325
5326       /* Insert another assignment which sets the '$size' field.  */
5327       lhs = gfc_copy_expr (code->expr1);
5328       gfc_add_component_ref (lhs, "$size");
5329       if (code->expr2->ts.type == BT_DERIVED)
5330         {
5331           /* Size is fixed at compile time.  */
5332           gfc_se lse;
5333           gfc_init_se (&lse, NULL);
5334           gfc_conv_expr (&lse, lhs);
5335           tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->expr2->ts));
5336           gfc_add_modify (&block, lse.expr,
5337                           fold_convert (TREE_TYPE (lse.expr), tmp));
5338         }
5339       else if (code->expr2->expr_type == EXPR_NULL)
5340         {
5341           rhs = gfc_int_expr (0);
5342           tmp = gfc_trans_assignment (lhs, rhs, false);
5343           gfc_add_expr_to_block (&block, tmp);
5344         }
5345       else
5346         gcc_unreachable ();
5347
5348       gfc_free_expr (lhs);
5349       gfc_free_expr (rhs);
5350     }
5351
5352   /* Do the actual CLASS assignment.  */
5353   if (code->expr2->ts.type == BT_CLASS)
5354     code->op = EXEC_ASSIGN;
5355   else
5356     gfc_add_component_ref (code->expr1, "$data");
5357
5358   if (code->op == EXEC_ASSIGN)
5359     tmp = gfc_trans_assign (code);
5360   else if (code->op == EXEC_POINTER_ASSIGN)
5361     tmp = gfc_trans_pointer_assign (code);
5362   else
5363     gcc_unreachable();
5364
5365   gfc_add_expr_to_block (&block, tmp);
5366
5367   return gfc_finish_block (&block);
5368 }