summaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-common.c
diff options
context:
space:
mode:
authorburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>2013-05-20 20:03:48 +0000
committerburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>2013-05-20 20:03:48 +0000
commit7a914593ca6c0be50165cad4fe5ae7909ab19827 (patch)
tree73668c05f30962cb8036747eb6744fb502ce15b9 /gcc/fortran/trans-common.c
parent65b7c3044e1e355984408d457ddad933af288fa6 (diff)
downloadgcc-7a914593ca6c0be50165cad4fe5ae7909ab19827.tar.gz
2013-05-20 Tobias Burnus <burnus@net-b.de>
PR fortran/48858 * decl.c (gfc_match_bind_c_stmt): Add gfc_notify_std. * match.c (gfc_match_common): Don't add commons to gsym. * resolve.c (resolve_common_blocks): Add to gsym and add checks. (resolve_bind_c_comms): Remove. (resolve_types): Remove call to the latter. * trans-common.c (gfc_common_ns): Remove static var. (gfc_map_of_all_commons): Add static var. (build_common_decl): Correctly handle binding label. 2013-05-20 Tobias Burnus <burnus@net-b.de> PR fortran/48858 * gfortran.dg/test_common_binding_labels.f03: Update dg-error. * gfortran.dg/test_common_binding_labels_2_main.f03: Ditto. * gfortran.dg/test_common_binding_labels_3_main.f03: Ditto. * gfortran.dg/common_18.f90: New. * gfortran.dg/common_19.f90: New. * gfortran.dg/common_20.f90: New. * gfortran.dg/common_21.f90: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199118 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/trans-common.c')
-rw-r--r--gcc/fortran/trans-common.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c
index db0f385d9b3..e2234b1ae0c 100644
--- a/gcc/fortran/trans-common.c
+++ b/gcc/fortran/trans-common.c
@@ -92,6 +92,7 @@ along with GCC; see the file COPYING3. If not see
is examined for still-unused equivalence conditions. We create a
block for each merged equivalence list. */
+#include <map>
#include "config.h"
#include "system.h"
#include "coretypes.h"
@@ -116,7 +117,10 @@ typedef struct segment_info
} segment_info;
static segment_info * current_segment;
-static gfc_namespace *gfc_common_ns = NULL;
+
+/* Store decl of all common blocks in this translation unit; the first
+ tree is the identifier. */
+static std::map<tree, tree> gfc_map_of_all_commons;
/* Make a segment_info based on a symbol. */
@@ -374,15 +378,11 @@ build_equiv_decl (tree union_type, bool is_init, bool is_saved)
static tree
build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
{
- gfc_symbol *common_sym;
- tree decl;
+ tree decl, identifier;
- /* Create a namespace to store symbols for common blocks. */
- if (gfc_common_ns == NULL)
- gfc_common_ns = gfc_get_namespace (NULL, 0);
-
- gfc_get_symbol (com->name, gfc_common_ns, &common_sym);
- decl = common_sym->backend_decl;
+ identifier = gfc_sym_mangled_common_id (com);
+ decl = gfc_map_of_all_commons.count(identifier)
+ ? gfc_map_of_all_commons[identifier] : NULL_TREE;
/* Update the size of this common block as needed. */
if (decl != NULL_TREE)
@@ -419,9 +419,15 @@ build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
/* If there is no backend_decl for the common block, build it. */
if (decl == NULL_TREE)
{
- decl = build_decl (input_location,
- VAR_DECL, get_identifier (com->name), union_type);
- gfc_set_decl_assembler_name (decl, gfc_sym_mangled_common_id (com));
+ if (com->is_bind_c == 1 && com->binding_label)
+ decl = build_decl (input_location, VAR_DECL, identifier, union_type);
+ else
+ {
+ decl = build_decl (input_location, VAR_DECL, get_identifier (com->name),
+ union_type);
+ gfc_set_decl_assembler_name (decl, identifier);
+ }
+
TREE_PUBLIC (decl) = 1;
TREE_STATIC (decl) = 1;
DECL_IGNORED_P (decl) = 1;
@@ -449,7 +455,7 @@ build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
/* Place the back end declaration for this common block in
GLOBAL_BINDING_LEVEL. */
- common_sym->backend_decl = pushdecl_top_level (decl);
+ gfc_map_of_all_commons[identifier] = pushdecl_top_level (decl);
}
/* Has no initial values. */