]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans-common.c
re PR libgcj/30742 (ResourceBundle regression)
[thirdparty/gcc.git] / gcc / fortran / trans-common.c
CommitLineData
6de9cd9a 1/* Common block and equivalence list handling
6c7a4dfd
JJ
2 Copyright (C) 2000, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc.
6de9cd9a
DN
4 Contributed by Canqun Yang <canqun@nudt.edu.cn>
5
9fc4d79b 6This file is part of GCC.
6de9cd9a 7
9fc4d79b
TS
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
6de9cd9a 12
9fc4d79b
TS
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
6de9cd9a
DN
17
18You should have received a copy of the GNU General Public License
9fc4d79b 19along with GCC; see the file COPYING. If not, write to the Free
ab57747b
KC
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA. */
6de9cd9a
DN
22
23/* The core algorithm is based on Andy Vaught's g95 tree. Also the
24 way to build UNION_TYPE is borrowed from Richard Henderson.
25
26 Transform common blocks. An integral part of this is processing
1f2959f0 27 equivalence variables. Equivalenced variables that are not in a
6de9cd9a
DN
28 common block end up in a private block of their own.
29
30 Each common block or local equivalence list is declared as a union.
31 Variables within the block are represented as a field within the
32 block with the proper offset.
33
34 So if two variables are equivalenced, they just point to a common
35 area in memory.
36
37 Mathematically, laying out an equivalence block is equivalent to
38 solving a linear system of equations. The matrix is usually a
39 sparse matrix in which each row contains all zero elements except
40 for a +1 and a -1, a sort of a generalized Vandermonde matrix. The
41 matrix is usually block diagonal. The system can be
42 overdetermined, underdetermined or have a unique solution. If the
43 system is inconsistent, the program is not standard conforming.
44 The solution vector is integral, since all of the pivots are +1 or -1.
45
46 How we lay out an equivalence block is a little less complicated.
47 In an equivalence list with n elements, there are n-1 conditions to
48 be satisfied. The conditions partition the variables into what we
49 will call segments. If A and B are equivalenced then A and B are
50 in the same segment. If B and C are equivalenced as well, then A,
51 B and C are in a segment and so on. Each segment is a block of
52 memory that has one or more variables equivalenced in some way. A
53 common block is made up of a series of segments that are joined one
54 after the other. In the linear system, a segment is a block
55 diagonal.
56
57 To lay out a segment we first start with some variable and
58 determine its length. The first variable is assumed to start at
59 offset one and extends to however long it is. We then traverse the
60 list of equivalences to find an unused condition that involves at
61 least one of the variables currently in the segment.
62
63 Each equivalence condition amounts to the condition B+b=C+c where B
64 and C are the offsets of the B and C variables, and b and c are
65 constants which are nonzero for array elements, substrings or
66 structure components. So for
67
68 EQUIVALENCE(B(2), C(3))
69 we have
70 B + 2*size of B's elements = C + 3*size of C's elements.
71
72 If B and C are known we check to see if the condition already
73 holds. If B is known we can solve for C. Since we know the length
74 of C, we can see if the minimum and maximum extents of the segment
75 are affected. Eventually, we make a full pass through the
76 equivalence list without finding any new conditions and the segment
77 is fully specified.
78
79 At this point, the segment is added to the current common block.
80 Since we know the minimum extent of the segment, everything in the
81 segment is translated to its position in the common block. The
82 usual case here is that there are no equivalence statements and the
83 common block is series of segments with one variable each, which is
84 a diagonal matrix in the matrix formulation.
85
5291e69a 86 Each segment is described by a chain of segment_info structures. Each
e2ae1407 87 segment_info structure describes the extents of a single variable within
5291e69a
PB
88 the segment. This list is maintained in the order the elements are
89 positioned withing the segment. If two elements have the same starting
90 offset the smaller will come first. If they also have the same size their
91 ordering is undefined.
92
6de9cd9a
DN
93 Once all common blocks have been created, the list of equivalences
94 is examined for still-unused equivalence conditions. We create a
95 block for each merged equivalence list. */
96
97#include "config.h"
98#include "system.h"
99#include "coretypes.h"
6c7a4dfd 100#include "target.h"
6de9cd9a
DN
101#include "tree.h"
102#include "toplev.h"
103#include "tm.h"
25f2dfd3 104#include "rtl.h"
6de9cd9a
DN
105#include "gfortran.h"
106#include "trans.h"
107#include "trans-types.h"
108#include "trans-const.h"
109
110
49de9e73 111/* Holds a single variable in an equivalence set. */
6de9cd9a
DN
112typedef struct segment_info
113{
114 gfc_symbol *sym;
5291e69a
PB
115 HOST_WIDE_INT offset;
116 HOST_WIDE_INT length;
ad6e2a18 117 /* This will contain the field type until the field is created. */
a8a6b603 118 tree field;
6de9cd9a
DN
119 struct segment_info *next;
120} segment_info;
121
832ef1ce 122static segment_info * current_segment;
6de9cd9a
DN
123static gfc_namespace *gfc_common_ns = NULL;
124
61321991 125
ad6e2a18
TS
126/* Make a segment_info based on a symbol. */
127
128static segment_info *
129get_segment_info (gfc_symbol * sym, HOST_WIDE_INT offset)
130{
131 segment_info *s;
132
133 /* Make sure we've got the character length. */
134 if (sym->ts.type == BT_CHARACTER)
135 gfc_conv_const_charlen (sym->ts.cl);
136
137 /* Create the segment_info and fill it in. */
138 s = (segment_info *) gfc_getmem (sizeof (segment_info));
139 s->sym = sym;
13795658 140 /* We will use this type when building the segment aggregate type. */
ad6e2a18
TS
141 s->field = gfc_sym_type (sym);
142 s->length = int_size_in_bytes (s->field);
143 s->offset = offset;
144
145 return s;
146}
147
61321991
PT
148
149/* Add a copy of a segment list to the namespace. This is specifically for
150 equivalence segments, so that dependency checking can be done on
151 equivalence group members. */
152
153static void
154copy_equiv_list_to_ns (segment_info *c)
155{
156 segment_info *f;
157 gfc_equiv_info *s;
158 gfc_equiv_list *l;
159
160 l = (gfc_equiv_list *) gfc_getmem (sizeof (gfc_equiv_list));
161
162 l->next = c->sym->ns->equiv_lists;
163 c->sym->ns->equiv_lists = l;
164
165 for (f = c; f; f = f->next)
166 {
167 s = (gfc_equiv_info *) gfc_getmem (sizeof (gfc_equiv_info));
168 s->next = l->equiv;
169 l->equiv = s;
170 s->sym = f->sym;
171 s->offset = f->offset;
37311e71 172 s->length = f->length;
61321991
PT
173 }
174}
175
176
a8a6b603 177/* Add combine segment V and segment LIST. */
5291e69a
PB
178
179static segment_info *
180add_segments (segment_info *list, segment_info *v)
181{
182 segment_info *s;
183 segment_info *p;
184 segment_info *next;
a8a6b603 185
5291e69a
PB
186 p = NULL;
187 s = list;
188
189 while (v)
190 {
191 /* Find the location of the new element. */
192 while (s)
193 {
194 if (v->offset < s->offset)
195 break;
196 if (v->offset == s->offset
197 && v->length <= s->length)
198 break;
199
200 p = s;
201 s = s->next;
202 }
203
204 /* Insert the new element in between p and s. */
205 next = v->next;
206 v->next = s;
207 if (p == NULL)
208 list = v;
209 else
210 p->next = v;
211
212 p = v;
213 v = next;
214 }
a8a6b603 215
5291e69a
PB
216 return list;
217}
218
6de9cd9a
DN
219/* Construct mangled common block name from symbol name. */
220
221static tree
41433497 222gfc_sym_mangled_common_id (const char *name)
6de9cd9a
DN
223{
224 int has_underscore;
9056bd70 225 char mangled_name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
6de9cd9a 226
9056bd70
TS
227 if (strcmp (name, BLANK_COMMON_NAME) == 0)
228 return get_identifier (name);
a8a6b603 229
6de9cd9a
DN
230 if (gfc_option.flag_underscoring)
231 {
9056bd70 232 has_underscore = strchr (name, '_') != 0;
6de9cd9a 233 if (gfc_option.flag_second_underscore && has_underscore)
9056bd70 234 snprintf (mangled_name, sizeof mangled_name, "%s__", name);
6de9cd9a 235 else
9056bd70 236 snprintf (mangled_name, sizeof mangled_name, "%s_", name);
a8a6b603 237
9056bd70 238 return get_identifier (mangled_name);
6de9cd9a
DN
239 }
240 else
9056bd70 241 return get_identifier (name);
6de9cd9a
DN
242}
243
244
ad6e2a18 245/* Build a field declaration for a common variable or a local equivalence
6de9cd9a
DN
246 object. */
247
ad6e2a18 248static void
6de9cd9a
DN
249build_field (segment_info *h, tree union_type, record_layout_info rli)
250{
ad6e2a18
TS
251 tree field;
252 tree name;
6de9cd9a 253 HOST_WIDE_INT offset = h->offset;
5291e69a 254 unsigned HOST_WIDE_INT desired_align, known_align;
6de9cd9a 255
ad6e2a18
TS
256 name = get_identifier (h->sym->name);
257 field = build_decl (FIELD_DECL, name, h->field);
c8cc8542 258 gfc_set_decl_location (field, &h->sym->declared_at);
6de9cd9a
DN
259 known_align = (offset & -offset) * BITS_PER_UNIT;
260 if (known_align == 0 || known_align > BIGGEST_ALIGNMENT)
261 known_align = BIGGEST_ALIGNMENT;
262
263 desired_align = update_alignment_for_field (rli, field, known_align);
264 if (desired_align > known_align)
265 DECL_PACKED (field) = 1;
266
267 DECL_FIELD_CONTEXT (field) = union_type;
268 DECL_FIELD_OFFSET (field) = size_int (offset);
269 DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
270 SET_DECL_OFFSET_ALIGN (field, known_align);
271
272 rli->offset = size_binop (MAX_EXPR, rli->offset,
273 size_binop (PLUS_EXPR,
274 DECL_FIELD_OFFSET (field),
275 DECL_SIZE_UNIT (field)));
ce2df7c6 276 /* If this field is assigned to a label, we create another two variables.
81871c2a 277 One will hold the address of target label or format label. The other will
ce2df7c6
FW
278 hold the length of format label string. */
279 if (h->sym->attr.assign)
280 {
281 tree len;
282 tree addr;
283
284 gfc_allocate_lang_decl (field);
285 GFC_DECL_ASSIGN (field) = 1;
286 len = gfc_create_var_np (gfc_charlen_type_node,h->sym->name);
287 addr = gfc_create_var_np (pvoid_type_node, h->sym->name);
288 TREE_STATIC (len) = 1;
289 TREE_STATIC (addr) = 1;
290 DECL_INITIAL (len) = build_int_cst (NULL_TREE, -2);
291 gfc_set_decl_location (len, &h->sym->declared_at);
292 gfc_set_decl_location (addr, &h->sym->declared_at);
293 GFC_DECL_STRING_LEN (field) = pushdecl_top_level (len);
294 GFC_DECL_ASSIGN_ADDR (field) = pushdecl_top_level (addr);
295 }
296
ad6e2a18 297 h->field = field;
6de9cd9a
DN
298}
299
300
301/* Get storage for local equivalence. */
302
303static tree
57f0d086 304build_equiv_decl (tree union_type, bool is_init, bool is_saved)
6de9cd9a
DN
305{
306 tree decl;
bae88af6
TS
307 char name[15];
308 static int serial = 0;
5291e69a
PB
309
310 if (is_init)
311 {
312 decl = gfc_create_var (union_type, "equiv");
313 TREE_STATIC (decl) = 1;
6c7a4dfd 314 GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
5291e69a
PB
315 return decl;
316 }
317
bae88af6
TS
318 snprintf (name, sizeof (name), "equiv.%d", serial++);
319 decl = build_decl (VAR_DECL, get_identifier (name), union_type);
6de9cd9a 320 DECL_ARTIFICIAL (decl) = 1;
bae88af6 321 DECL_IGNORED_P (decl) = 1;
6de9cd9a 322
57f0d086
JJ
323 if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
324 || is_saved)
bae88af6 325 TREE_STATIC (decl) = 1;
6de9cd9a
DN
326
327 TREE_ADDRESSABLE (decl) = 1;
328 TREE_USED (decl) = 1;
6c7a4dfd 329 GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
c8cc8542
PB
330
331 /* The source location has been lost, and doesn't really matter.
332 We need to set it to something though. */
333 gfc_set_decl_location (decl, &gfc_current_locus);
334
6de9cd9a
DN
335 gfc_add_decl_to_function (decl);
336
337 return decl;
338}
339
340
341/* Get storage for common block. */
342
343static tree
53814b8f 344build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
6de9cd9a
DN
345{
346 gfc_symbol *common_sym;
347 tree decl;
348
349 /* Create a namespace to store symbols for common blocks. */
350 if (gfc_common_ns == NULL)
0366dfe9 351 gfc_common_ns = gfc_get_namespace (NULL, 0);
6de9cd9a 352
53814b8f 353 gfc_get_symbol (com->name, gfc_common_ns, &common_sym);
6de9cd9a
DN
354 decl = common_sym->backend_decl;
355
356 /* Update the size of this common block as needed. */
357 if (decl != NULL_TREE)
358 {
5291e69a 359 tree size = TYPE_SIZE_UNIT (union_type);
6de9cd9a
DN
360 if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size))
361 {
362 /* Named common blocks of the same name shall be of the same size
363 in all scoping units of a program in which they appear, but
364 blank common blocks may be of different sizes. */
53814b8f 365 if (strcmp (com->name, BLANK_COMMON_NAME))
a8a6b603 366 gfc_warning ("Named COMMON block '%s' at %L shall be of the "
53814b8f 367 "same size", com->name, &com->where);
6de9cd9a
DN
368 DECL_SIZE_UNIT (decl) = size;
369 }
370 }
371
372 /* If this common block has been declared in a previous program unit,
373 and either it is already initialized or there is no new initialization
374 for it, just return. */
375 if ((decl != NULL_TREE) && (!is_init || DECL_INITIAL (decl)))
376 return decl;
377
378 /* If there is no backend_decl for the common block, build it. */
379 if (decl == NULL_TREE)
380 {
53814b8f
TS
381 decl = build_decl (VAR_DECL, get_identifier (com->name), union_type);
382 SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (com->name));
6de9cd9a
DN
383 TREE_PUBLIC (decl) = 1;
384 TREE_STATIC (decl) = 1;
385 DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
386 DECL_USER_ALIGN (decl) = 0;
6c7a4dfd 387 GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
5291e69a 388
c8cc8542
PB
389 gfc_set_decl_location (decl, &com->where);
390
a98d4769 391 if (com->threadprivate && targetm.have_tls)
6c7a4dfd
JJ
392 DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
393
5291e69a
PB
394 /* Place the back end declaration for this common block in
395 GLOBAL_BINDING_LEVEL. */
396 common_sym->backend_decl = pushdecl_top_level (decl);
6de9cd9a
DN
397 }
398
399 /* Has no initial values. */
400 if (!is_init)
401 {
402 DECL_INITIAL (decl) = NULL_TREE;
403 DECL_COMMON (decl) = 1;
404 DECL_DEFER_OUTPUT (decl) = 1;
6de9cd9a
DN
405 }
406 else
407 {
408 DECL_INITIAL (decl) = error_mark_node;
409 DECL_COMMON (decl) = 0;
410 DECL_DEFER_OUTPUT (decl) = 0;
6de9cd9a
DN
411 }
412 return decl;
413}
414
415
416/* Declare memory for the common block or local equivalence, and create
417 backend declarations for all of the elements. */
418
419static void
a3122424 420create_common (gfc_common_head *com, segment_info * head, bool saw_equiv)
a8a6b603
TS
421{
422 segment_info *s, *next_s;
6de9cd9a
DN
423 tree union_type;
424 tree *field_link;
425 record_layout_info rli;
426 tree decl;
427 bool is_init = false;
57f0d086 428 bool is_saved = false;
6de9cd9a 429
a3122424
CY
430 /* Declare the variables inside the common block.
431 If the current common block contains any equivalence object, then
432 make a UNION_TYPE node, otherwise RECORD_TYPE. This will let the
433 alias analyzer work well when there is no address overlapping for
434 common variables in the current common block. */
435 if (saw_equiv)
436 union_type = make_node (UNION_TYPE);
437 else
438 union_type = make_node (RECORD_TYPE);
439
6de9cd9a
DN
440 rli = start_record_layout (union_type);
441 field_link = &TYPE_FIELDS (union_type);
442
832ef1ce 443 for (s = head; s; s = s->next)
6de9cd9a 444 {
a8a6b603 445 build_field (s, union_type, rli);
6de9cd9a
DN
446
447 /* Link the field into the type. */
a8a6b603
TS
448 *field_link = s->field;
449 field_link = &TREE_CHAIN (s->field);
ad6e2a18 450
a8a6b603
TS
451 /* Has initial value. */
452 if (s->sym->value)
6de9cd9a 453 is_init = true;
57f0d086
JJ
454
455 /* Has SAVE attribute. */
456 if (s->sym->attr.save)
457 is_saved = true;
6de9cd9a
DN
458 }
459 finish_record_layout (rli, true);
460
9056bd70 461 if (com)
53814b8f 462 decl = build_common_decl (com, union_type, is_init);
6de9cd9a 463 else
57f0d086 464 decl = build_equiv_decl (union_type, is_init, is_saved);
6de9cd9a 465
5291e69a
PB
466 if (is_init)
467 {
4038c495 468 tree ctor, tmp;
5291e69a 469 HOST_WIDE_INT offset = 0;
4038c495 470 VEC(constructor_elt,gc) *v = NULL;
5291e69a 471
832ef1ce 472 for (s = head; s; s = s->next)
5291e69a 473 {
a8a6b603 474 if (s->sym->value)
5291e69a 475 {
a8a6b603 476 if (s->offset < offset)
5291e69a
PB
477 {
478 /* We have overlapping initializers. It could either be
1f2959f0 479 partially initialized arrays (legal), or the user
5291e69a
PB
480 specified multiple initial values (illegal).
481 We don't implement this yet, so bail out. */
482 gfc_todo_error ("Initialization of overlapping variables");
483 }
597073ac
PB
484 /* Add the initializer for this field. */
485 tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
486 TREE_TYPE (s->field), s->sym->attr.dimension,
487 s->sym->attr.pointer || s->sym->attr.allocatable);
4038c495
GB
488
489 CONSTRUCTOR_APPEND_ELT (v, s->field, tmp);
a8a6b603 490 offset = s->offset + s->length;
5291e69a
PB
491 }
492 }
4038c495
GB
493 gcc_assert (!VEC_empty (constructor_elt, v));
494 ctor = build_constructor (union_type, v);
5291e69a
PB
495 TREE_CONSTANT (ctor) = 1;
496 TREE_INVARIANT (ctor) = 1;
497 TREE_STATIC (ctor) = 1;
498 DECL_INITIAL (decl) = ctor;
499
500#ifdef ENABLE_CHECKING
4038c495
GB
501 {
502 tree field, value;
503 unsigned HOST_WIDE_INT idx;
504 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, field, value)
505 gcc_assert (TREE_CODE (field) == FIELD_DECL);
506 }
5291e69a
PB
507#endif
508 }
509
6de9cd9a 510 /* Build component reference for each variable. */
832ef1ce 511 for (s = head; s; s = next_s)
6de9cd9a 512 {
81871c2a
JJ
513 tree var_decl;
514
515 var_decl = build_decl (VAR_DECL, DECL_NAME (s->field),
516 TREE_TYPE (s->field));
517 gfc_set_decl_location (var_decl, &s->sym->declared_at);
518 TREE_PUBLIC (var_decl) = TREE_PUBLIC (decl);
519 TREE_STATIC (var_decl) = TREE_STATIC (decl);
520 TREE_USED (var_decl) = TREE_USED (decl);
521 if (s->sym->attr.target)
522 TREE_ADDRESSABLE (var_decl) = 1;
523 /* This is a fake variable just for debugging purposes. */
524 TREE_ASM_WRITTEN (var_decl) = 1;
525
526 if (com)
527 var_decl = pushdecl_top_level (var_decl);
528 else
529 gfc_add_decl_to_function (var_decl);
530
531 SET_DECL_VALUE_EXPR (var_decl,
532 build3 (COMPONENT_REF, TREE_TYPE (s->field),
533 decl, s->field, NULL_TREE));
534 DECL_HAS_VALUE_EXPR_P (var_decl) = 1;
6c7a4dfd 535 GFC_DECL_COMMON_OR_EQUIV (var_decl) = 1;
81871c2a
JJ
536
537 if (s->sym->attr.assign)
538 {
539 gfc_allocate_lang_decl (var_decl);
540 GFC_DECL_ASSIGN (var_decl) = 1;
541 GFC_DECL_STRING_LEN (var_decl) = GFC_DECL_STRING_LEN (s->field);
542 GFC_DECL_ASSIGN_ADDR (var_decl) = GFC_DECL_ASSIGN_ADDR (s->field);
543 }
544
545 s->sym->backend_decl = var_decl;
6de9cd9a 546
a8a6b603
TS
547 next_s = s->next;
548 gfc_free (s);
6de9cd9a 549 }
a8a6b603 550}
6de9cd9a
DN
551
552
553/* Given a symbol, find it in the current segment list. Returns NULL if
a8a6b603 554 not found. */
6de9cd9a 555
a8a6b603 556static segment_info *
6de9cd9a 557find_segment_info (gfc_symbol *symbol)
a8a6b603 558{
6de9cd9a
DN
559 segment_info *n;
560
561 for (n = current_segment; n; n = n->next)
5291e69a
PB
562 {
563 if (n->sym == symbol)
564 return n;
565 }
6de9cd9a 566
a8a6b603
TS
567 return NULL;
568}
6de9cd9a
DN
569
570
6de9cd9a 571/* Given an expression node, make sure it is a constant integer and return
a8a6b603 572 the mpz_t value. */
6de9cd9a 573
a8a6b603
TS
574static mpz_t *
575get_mpz (gfc_expr *e)
6de9cd9a 576{
a8a6b603
TS
577
578 if (e->expr_type != EXPR_CONSTANT)
6de9cd9a
DN
579 gfc_internal_error ("get_mpz(): Not an integer constant");
580
a8a6b603
TS
581 return &e->value.integer;
582}
6de9cd9a
DN
583
584
585/* Given an array specification and an array reference, figure out the
586 array element number (zero based). Bounds and elements are guaranteed
587 to be constants. If something goes wrong we generate an error and
a8a6b603 588 return zero. */
6de9cd9a 589
5291e69a 590static HOST_WIDE_INT
6de9cd9a 591element_number (gfc_array_ref *ar)
a8a6b603
TS
592{
593 mpz_t multiplier, offset, extent, n;
6de9cd9a 594 gfc_array_spec *as;
a8a6b603 595 HOST_WIDE_INT i, rank;
6de9cd9a
DN
596
597 as = ar->as;
598 rank = as->rank;
599 mpz_init_set_ui (multiplier, 1);
600 mpz_init_set_ui (offset, 0);
601 mpz_init (extent);
a8a6b603 602 mpz_init (n);
6de9cd9a 603
a8a6b603 604 for (i = 0; i < rank; i++)
6de9cd9a 605 {
a8a6b603 606 if (ar->dimen_type[i] != DIMEN_ELEMENT)
6de9cd9a
DN
607 gfc_internal_error ("element_number(): Bad dimension type");
608
a8a6b603 609 mpz_sub (n, *get_mpz (ar->start[i]), *get_mpz (as->lower[i]));
6de9cd9a 610
a8a6b603
TS
611 mpz_mul (n, n, multiplier);
612 mpz_add (offset, offset, n);
6de9cd9a 613
a8a6b603 614 mpz_sub (extent, *get_mpz (as->upper[i]), *get_mpz (as->lower[i]));
6de9cd9a
DN
615 mpz_add_ui (extent, extent, 1);
616
617 if (mpz_sgn (extent) < 0)
618 mpz_set_ui (extent, 0);
619
620 mpz_mul (multiplier, multiplier, extent);
621 }
622
a8a6b603 623 i = mpz_get_ui (offset);
6de9cd9a
DN
624
625 mpz_clear (multiplier);
626 mpz_clear (offset);
627 mpz_clear (extent);
a8a6b603 628 mpz_clear (n);
6de9cd9a 629
a8a6b603 630 return i;
6de9cd9a
DN
631}
632
633
634/* Given a single element of an equivalence list, figure out the offset
635 from the base symbol. For simple variables or full arrays, this is
636 simply zero. For an array element we have to calculate the array
637 element number and multiply by the element size. For a substring we
638 have to calculate the further reference. */
639
5291e69a 640static HOST_WIDE_INT
a8a6b603 641calculate_offset (gfc_expr *e)
6de9cd9a 642{
a8a6b603 643 HOST_WIDE_INT n, element_size, offset;
6de9cd9a
DN
644 gfc_typespec *element_type;
645 gfc_ref *reference;
646
647 offset = 0;
a8a6b603 648 element_type = &e->symtree->n.sym->ts;
6de9cd9a 649
a8a6b603 650 for (reference = e->ref; reference; reference = reference->next)
6de9cd9a
DN
651 switch (reference->type)
652 {
653 case REF_ARRAY:
654 switch (reference->u.ar.type)
655 {
656 case AR_FULL:
657 break;
658
659 case AR_ELEMENT:
a8a6b603 660 n = element_number (&reference->u.ar);
6de9cd9a
DN
661 if (element_type->type == BT_CHARACTER)
662 gfc_conv_const_charlen (element_type->cl);
663 element_size =
664 int_size_in_bytes (gfc_typenode_for_spec (element_type));
a8a6b603 665 offset += n * element_size;
6de9cd9a
DN
666 break;
667
668 default:
a8a6b603 669 gfc_error ("Bad array reference at %L", &e->where);
6de9cd9a
DN
670 }
671 break;
672 case REF_SUBSTRING:
673 if (reference->u.ss.start != NULL)
674 offset += mpz_get_ui (*get_mpz (reference->u.ss.start)) - 1;
675 break;
676 default:
5291e69a 677 gfc_error ("Illegal reference type at %L as EQUIVALENCE object",
a8a6b603
TS
678 &e->where);
679 }
6de9cd9a
DN
680 return offset;
681}
682
a8a6b603 683
5291e69a
PB
684/* Add a new segment_info structure to the current segment. eq1 is already
685 in the list, eq2 is not. */
6de9cd9a
DN
686
687static void
688new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
689{
5291e69a 690 HOST_WIDE_INT offset1, offset2;
6de9cd9a 691 segment_info *a;
a8a6b603 692
6de9cd9a
DN
693 offset1 = calculate_offset (eq1->expr);
694 offset2 = calculate_offset (eq2->expr);
695
ad6e2a18
TS
696 a = get_segment_info (eq2->expr->symtree->n.sym,
697 v->offset + offset1 - offset2);
6de9cd9a 698
5291e69a 699 current_segment = add_segments (current_segment, a);
6de9cd9a
DN
700}
701
702
703/* Given two equivalence structures that are both already in the list, make
704 sure that this new condition is not violated, generating an error if it
705 is. */
706
707static void
a8a6b603 708confirm_condition (segment_info *s1, gfc_equiv *eq1, segment_info *s2,
6de9cd9a
DN
709 gfc_equiv *eq2)
710{
5291e69a 711 HOST_WIDE_INT offset1, offset2;
6de9cd9a
DN
712
713 offset1 = calculate_offset (eq1->expr);
714 offset2 = calculate_offset (eq2->expr);
a8a6b603
TS
715
716 if (s1->offset + offset1 != s2->offset + offset2)
5291e69a 717 gfc_error ("Inconsistent equivalence rules involving '%s' at %L and "
a8a6b603
TS
718 "'%s' at %L", s1->sym->name, &s1->sym->declared_at,
719 s2->sym->name, &s2->sym->declared_at);
720}
721
6de9cd9a 722
5291e69a
PB
723/* Process a new equivalence condition. eq1 is know to be in segment f.
724 If eq2 is also present then confirm that the condition holds.
725 Otherwise add a new variable to the segment list. */
6de9cd9a
DN
726
727static void
5291e69a 728add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
6de9cd9a 729{
5291e69a 730 segment_info *n;
6de9cd9a 731
5291e69a 732 n = find_segment_info (eq2->expr->symtree->n.sym);
6de9cd9a 733
5291e69a
PB
734 if (n == NULL)
735 new_condition (f, eq1, eq2);
736 else
737 confirm_condition (f, eq1, n, eq2);
6de9cd9a
DN
738}
739
740
5291e69a 741/* Given a segment element, search through the equivalence lists for unused
30aabb86
PT
742 conditions that involve the symbol. Add these rules to the segment. */
743
5291e69a 744static bool
a8a6b603 745find_equivalence (segment_info *n)
6de9cd9a 746{
30aabb86 747 gfc_equiv *e1, *e2, *eq;
5291e69a 748 bool found;
30aabb86 749
5291e69a 750 found = FALSE;
30aabb86 751
a8a6b603 752 for (e1 = n->sym->ns->equiv; e1; e1 = e1->next)
5291e69a 753 {
30aabb86 754 eq = NULL;
5291e69a 755
30aabb86
PT
756 /* Search the equivalence list, including the root (first) element
757 for the symbol that owns the segment. */
758 for (e2 = e1; e2; e2 = e2->eq)
759 {
760 if (!e2->used && e2->expr->symtree->n.sym == n->sym)
5291e69a 761 {
a8a6b603 762 eq = e2;
30aabb86 763 break;
5291e69a 764 }
30aabb86
PT
765 }
766
767 /* Go to the next root element. */
768 if (eq == NULL)
769 continue;
770
771 eq->used = 1;
772
773 /* Now traverse the equivalence list matching the offsets. */
774 for (e2 = e1; e2; e2 = e2->eq)
775 {
776 if (!e2->used && e2 != eq)
5291e69a 777 {
30aabb86
PT
778 add_condition (n, eq, e2);
779 e2->used = 1;
5291e69a 780 found = TRUE;
5291e69a
PB
781 }
782 }
783 }
784 return found;
6de9cd9a
DN
785}
786
a8a6b603 787
8a0b57b3
PT
788 /* Add all symbols equivalenced within a segment. We need to scan the
789 segment list multiple times to include indirect equivalences. Since
790 a new segment_info can inserted at the beginning of the segment list,
791 depending on its offset, we have to force a final pass through the
792 loop by demanding that completion sees a pass with no matches; ie.
793 all symbols with equiv_built set and no new equivalences found. */
6de9cd9a 794
5291e69a 795static void
a3122424 796add_equivalences (bool *saw_equiv)
6de9cd9a 797{
6de9cd9a 798 segment_info *f;
8a0b57b3 799 bool seen_one, more;
6de9cd9a 800
8a0b57b3 801 seen_one = false;
5291e69a
PB
802 more = TRUE;
803 while (more)
6de9cd9a 804 {
5291e69a
PB
805 more = FALSE;
806 for (f = current_segment; f; f = f->next)
807 {
808 if (!f->sym->equiv_built)
809 {
810 f->sym->equiv_built = 1;
8a0b57b3
PT
811 seen_one = find_equivalence (f);
812 if (seen_one)
813 {
814 *saw_equiv = true;
815 more = true;
816 }
5291e69a
PB
817 }
818 }
6de9cd9a 819 }
61321991
PT
820
821 /* Add a copy of this segment list to the namespace. */
822 copy_equiv_list_to_ns (current_segment);
6de9cd9a 823}
a8a6b603
TS
824
825
43a5ef69 826/* Returns the offset necessary to properly align the current equivalence.
832ef1ce
PB
827 Sets *palign to the required alignment. */
828
829static HOST_WIDE_INT
830align_segment (unsigned HOST_WIDE_INT * palign)
831{
832 segment_info *s;
833 unsigned HOST_WIDE_INT offset;
834 unsigned HOST_WIDE_INT max_align;
835 unsigned HOST_WIDE_INT this_align;
836 unsigned HOST_WIDE_INT this_offset;
837
838 max_align = 1;
839 offset = 0;
840 for (s = current_segment; s; s = s->next)
841 {
842 this_align = TYPE_ALIGN_UNIT (s->field);
843 if (s->offset & (this_align - 1))
844 {
845 /* Field is misaligned. */
846 this_offset = this_align - ((s->offset + offset) & (this_align - 1));
847 if (this_offset & (max_align - 1))
848 {
849 /* Aligning this field would misalign a previous field. */
850 gfc_error ("The equivalence set for variable '%s' "
eb6d74fa 851 "declared at %L violates alignment requirements",
832ef1ce
PB
852 s->sym->name, &s->sym->declared_at);
853 }
854 offset += this_offset;
855 }
856 max_align = this_align;
857 }
858 if (palign)
859 *palign = max_align;
860 return offset;
861}
862
863
864/* Adjust segment offsets by the given amount. */
a8a6b603 865
6de9cd9a 866static void
832ef1ce 867apply_segment_offset (segment_info * s, HOST_WIDE_INT offset)
6de9cd9a 868{
832ef1ce
PB
869 for (; s; s = s->next)
870 s->offset += offset;
871}
872
873
874/* Lay out a symbol in a common block. If the symbol has already been seen
875 then check the location is consistent. Otherwise create segments
876 for that symbol and all the symbols equivalenced with it. */
877
878/* Translate a single common block. */
879
880static void
881translate_common (gfc_common_head *common, gfc_symbol *var_list)
882{
883 gfc_symbol *sym;
884 segment_info *s;
885 segment_info *common_segment;
886 HOST_WIDE_INT offset;
887 HOST_WIDE_INT current_offset;
888 unsigned HOST_WIDE_INT align;
889 unsigned HOST_WIDE_INT max_align;
a3122424 890 bool saw_equiv;
832ef1ce
PB
891
892 common_segment = NULL;
893 current_offset = 0;
894 max_align = 1;
a3122424 895 saw_equiv = false;
832ef1ce
PB
896
897 /* Add symbols to the segment. */
898 for (sym = var_list; sym; sym = sym->common_next)
899 {
30aabb86
PT
900 current_segment = common_segment;
901 s = find_segment_info (sym);
832ef1ce 902
30aabb86
PT
903 /* Symbol has already been added via an equivalence. Multiple
904 use associations of the same common block result in equiv_built
905 being set but no information about the symbol in the segment. */
906 if (s && sym->equiv_built)
907 {
832ef1ce
PB
908 /* Ensure the current location is properly aligned. */
909 align = TYPE_ALIGN_UNIT (s->field);
910 current_offset = (current_offset + align - 1) &~ (align - 1);
911
912 /* Verify that it ended up where we expect it. */
913 if (s->offset != current_offset)
914 {
915 gfc_error ("Equivalence for '%s' does not match ordering of "
916 "COMMON '%s' at %L", sym->name,
917 common->name, &common->where);
918 }
919 }
920 else
921 {
922 /* A symbol we haven't seen before. */
923 s = current_segment = get_segment_info (sym, current_offset);
a8a6b603 924
832ef1ce
PB
925 /* Add all objects directly or indirectly equivalenced with this
926 symbol. */
a3122424 927 add_equivalences (&saw_equiv);
ad6e2a18 928
832ef1ce
PB
929 if (current_segment->offset < 0)
930 gfc_error ("The equivalence set for '%s' cause an invalid "
931 "extension to COMMON '%s' at %L", sym->name,
932 common->name, &common->where);
6de9cd9a 933
832ef1ce 934 offset = align_segment (&align);
6de9cd9a 935
832ef1ce
PB
936 if (offset & (max_align - 1))
937 {
938 /* The required offset conflicts with previous alignment
939 requirements. Insert padding immediately before this
940 segment. */
941 gfc_warning ("Padding of %d bytes required before '%s' in "
eb83e811 942 "COMMON '%s' at %L", (int)offset, s->sym->name,
832ef1ce
PB
943 common->name, &common->where);
944 }
945 else
946 {
947 /* Offset the whole common block. */
948 apply_segment_offset (common_segment, offset);
949 }
6de9cd9a 950
832ef1ce
PB
951 /* Apply the offset to the new segments. */
952 apply_segment_offset (current_segment, offset);
953 current_offset += offset;
954 if (max_align < align)
955 max_align = align;
956
957 /* Add the new segments to the common block. */
958 common_segment = add_segments (common_segment, current_segment);
959 }
960
961 /* The offset of the next common variable. */
962 current_offset += s->length;
963 }
964
b8ea6dbc
PT
965 if (common_segment == NULL)
966 {
967 gfc_error ("COMMON '%s' at %L does not exist",
968 common->name, &common->where);
969 return;
970 }
971
832ef1ce
PB
972 if (common_segment->offset != 0)
973 {
974 gfc_warning ("COMMON '%s' at %L requires %d bytes of padding at start",
eb83e811 975 common->name, &common->where, (int)common_segment->offset);
832ef1ce
PB
976 }
977
a3122424 978 create_common (common, common_segment, saw_equiv);
6de9cd9a
DN
979}
980
981
982/* Create a new block for each merged equivalence list. */
983
984static void
985finish_equivalences (gfc_namespace *ns)
986{
987 gfc_equiv *z, *y;
988 gfc_symbol *sym;
30aabb86 989 gfc_common_head * c;
36c028f6
PB
990 HOST_WIDE_INT offset;
991 unsigned HOST_WIDE_INT align;
a3122424 992 bool dummy;
6de9cd9a
DN
993
994 for (z = ns->equiv; z; z = z->next)
a8a6b603 995 for (y = z->eq; y; y = y->eq)
6de9cd9a 996 {
a8a6b603
TS
997 if (y->used)
998 continue;
6de9cd9a 999 sym = z->expr->symtree->n.sym;
ad6e2a18 1000 current_segment = get_segment_info (sym, 0);
6de9cd9a 1001
1f2959f0 1002 /* All objects directly or indirectly equivalenced with this symbol. */
a3122424 1003 add_equivalences (&dummy);
6de9cd9a 1004
36c028f6
PB
1005 /* Align the block. */
1006 offset = align_segment (&align);
832ef1ce 1007
36c028f6
PB
1008 /* Ensure all offsets are positive. */
1009 offset -= current_segment->offset & ~(align - 1);
6de9cd9a 1010
36c028f6 1011 apply_segment_offset (current_segment, offset);
6de9cd9a 1012
30aabb86
PT
1013 /* Create the decl. If this is a module equivalence, it has a unique
1014 name, pointed to by z->module. This is written to a gfc_common_header
1015 to push create_common into using build_common_decl, so that the
1016 equivalence appears as an external symbol. Otherwise, a local
1017 declaration is built using build_equiv_decl.*/
1018 if (z->module)
1019 {
1020 c = gfc_get_common_head ();
1021 /* We've lost the real location, so use the location of the
1022 enclosing procedure. */
1023 c->where = ns->proc_name->declared_at;
1024 strcpy (c->name, z->module);
1025 }
1026 else
1027 c = NULL;
1028
1029 create_common (c, current_segment, true);
6de9cd9a
DN
1030 break;
1031 }
1032}
1033
1034
6de9cd9a
DN
1035/* Work function for translating a named common block. */
1036
1037static void
9056bd70 1038named_common (gfc_symtree *st)
6de9cd9a 1039{
53814b8f 1040 translate_common (st->n.common, st->n.common->head);
6de9cd9a
DN
1041}
1042
1043
1044/* Translate the common blocks in a namespace. Unlike other variables,
1045 these have to be created before code, because the backend_decl depends
1046 on the rest of the common block. */
a8a6b603
TS
1047
1048void
6de9cd9a
DN
1049gfc_trans_common (gfc_namespace *ns)
1050{
9056bd70 1051 gfc_common_head *c;
6de9cd9a
DN
1052
1053 /* Translate the blank common block. */
9056bd70 1054 if (ns->blank_common.head != NULL)
6de9cd9a 1055 {
9056bd70 1056 c = gfc_get_common_head ();
41433497 1057
c8cc8542
PB
1058 /* We've lost the real location, so use the location of the
1059 enclosing procedure. */
41433497
BF
1060 if (ns->proc_name != NULL)
1061 c->where = ns->proc_name->declared_at;
1062 else
1063 c->where = ns->blank_common.head->common_head->where;
1064
53814b8f
TS
1065 strcpy (c->name, BLANK_COMMON_NAME);
1066 translate_common (c, ns->blank_common.head);
6de9cd9a 1067 }
41433497 1068
6de9cd9a 1069 /* Translate all named common blocks. */
a8a6b603 1070 gfc_traverse_symtree (ns->common_root, named_common);
6de9cd9a 1071
6de9cd9a
DN
1072 /* Translate local equivalence. */
1073 finish_equivalences (ns);
613e2ac8
PT
1074
1075 /* Commit the newly created symbols for common blocks and module
1076 equivalences. */
1077 gfc_commit_symbols ();
6de9cd9a 1078}