diff options
author | Tobias Burnus <burnus@net-b.de> | 2012-04-15 07:52:51 +0200 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2012-04-15 07:52:51 +0200 |
commit | cdd244b8325261c691418991eaf78018e4be1d36 (patch) | |
tree | ebf6b57b3ef8ce310ea30d7ae5deff2e09d2a3e2 /gcc/fortran | |
parent | 9aad845a63596fb36cee7d359592bf53e1c6f416 (diff) | |
download | gcc-cdd244b8325261c691418991eaf78018e4be1d36.zip gcc-cdd244b8325261c691418991eaf78018e4be1d36.tar.gz gcc-cdd244b8325261c691418991eaf78018e4be1d36.tar.bz2 |
re PR fortran/52916 (481.wrf in SPEC CPU 2006 failed to build)
2012-04-14 Tobias Burnus <burnus@net-b.de>
PR fortran/52916
PR fortran/40973
* gfortran.h (symbol_attribute): Add public_used.
* interface.c (check_sym_interfaces, check_uop_interfaces,
gfc_check_interfaces): Set it.
* resolve.c (resolve_typebound_procedure): Ditto.
* trans-decl.c (build_function_decl): Use it.
2012-04-14 Tobias Burnus <burnus@net-b.de>
PR fortran/52916
PR fortran/40973
* gfortran.dg/public_private_module_3.f90: New.
* gfortran.dg/public_private_module_4.f90: New.
From-SVN: r186464
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 4 | ||||
-rw-r--r-- | gcc/fortran/interface.c | 13 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 1 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.c | 3 |
5 files changed, 30 insertions, 1 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 99063d3..9bb46ac 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2012-04-15 Tobias Burnus <burnus@net-b.de> + + PR fortran/52916 + PR fortran/40973 + * gfortran.h (symbol_attribute): Add public_used. + * interface.c (check_sym_interfaces, check_uop_interfaces, + gfc_check_interfaces): Set it. + * resolve.c (resolve_typebound_procedure): Ditto. + * trans-decl.c (build_function_decl): Use it. + 2012-04-11 Tobias Burnus <burnus@net-b.de> PR fortran/52729 diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 8e83cb4..25bdfa5 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -726,6 +726,10 @@ typedef struct unsigned sequence:1, elemental:1, pure:1, recursive:1; unsigned unmaskable:1, masked:1, contained:1, mod_proc:1, abstract:1; + /* Set if a (public) symbol [e.g. generic name] exposes this symbol, + which is relevant for private module procedures. */ + unsigned public_used:1; + /* This is set if a contained procedure could be declared pure. This is used for certain optimizations that require the result or arguments cannot alias. Note that this is zero for PURE procedures. */ diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 298ae23d..2f1d24e 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -1390,6 +1390,9 @@ check_sym_interfaces (gfc_symbol *sym) for (p = sym->generic; p; p = p->next) { + if (sym->attr.access != ACCESS_PRIVATE) + p->sym->attr.public_used = 1; + if (p->sym->attr.mod_proc && (p->sym->attr.if_source != IFSRC_DECL || p->sym->attr.procedure)) @@ -1415,11 +1418,16 @@ check_uop_interfaces (gfc_user_op *uop) char interface_name[100]; gfc_user_op *uop2; gfc_namespace *ns; + gfc_interface *p; sprintf (interface_name, "operator interface '%s'", uop->name); if (check_interface0 (uop->op, interface_name)) return; + if (uop->access != ACCESS_PRIVATE) + for (p = uop->op; p; p = p->next) + p->sym->attr.public_used = 1; + for (ns = gfc_current_ns; ns; ns = ns->parent) { uop2 = gfc_find_uop (uop->name, ns); @@ -1489,6 +1497,7 @@ void gfc_check_interfaces (gfc_namespace *ns) { gfc_namespace *old_ns, *ns2; + gfc_interface *p; char interface_name[100]; int i; @@ -1513,6 +1522,10 @@ gfc_check_interfaces (gfc_namespace *ns) if (check_interface0 (ns->op[i], interface_name)) continue; + for (p = ns->op[i]; p; p = p->next) + p->sym->attr.public_used = 1; + + if (ns->op[i]) gfc_check_operator_interface (ns->op[i]->sym, (gfc_intrinsic_op) i, ns->op[i]->where); diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 34b3e9e..57da577 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -11304,6 +11304,7 @@ resolve_typebound_procedure (gfc_symtree* stree) gcc_assert (stree->n.tb->u.specific); proc = stree->n.tb->u.specific->n.sym; where = stree->n.tb->where; + proc->attr.public_used = 1; /* Default access should already be resolved from the parser. */ gcc_assert (stree->n.tb->access != ACCESS_UNKNOWN); diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index aec96aa..129010e 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -1844,7 +1844,8 @@ build_function_decl (gfc_symbol * sym, bool global) if (!current_function_decl && !sym->attr.entry_master && !sym->attr.is_main_program - && (sym->attr.access != ACCESS_PRIVATE || sym->binding_label)) + && (sym->attr.access != ACCESS_PRIVATE || sym->binding_label + || sym->attr.public_used)) TREE_PUBLIC (fndecl) = 1; attributes = add_attributes_to_decl (attr, NULL_TREE); |