Commit a56ea54a by Paul Thomas

re PR fortran/52846 ([F2008] Support submodules)

2015-08-05  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/52846
	* module.c (check_access): Return true if new static flag
	'dump_smod' is true..
	(gfc_dump_module): Rename original 'dump_module' and call from
	new version. Use 'dump_smod' rather than the stack state to
	determine if a submodule is being processed. The new version of
	this procedure sets 'dump_smod' depending on the stack state and
	then writes both the mod and smod files if a module is being
	processed or just the smod for a submodule.
	(gfc_use_module): Eliminate the check for module_name and
	submodule_name being the same.
	* trans-decl.c (gfc_finish_var_decl, gfc_build_qualified_array,
	get_proc_pointer_decl): Set TREE_PUBLIC unconditionally and use
	the conditions to set DECL_VISIBILITY as hidden and to set as
	true DECL_VISIBILITY_SPECIFIED.

2015-08-05  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/52846

	* lib/fortran-modules.exp: Call cleanup-submodules from
	cleanup-modules.
	* gfortran.dg/public_private_module_2.f90: Add two XFAILS to
	cover the cases where private entities are no longer optimized
	away.
	* gfortran.dg/public_private_module_6.f90: Add an XFAIL for the
	same reason.
	* gfortran.dg/submodule_1.f08: Change cleanup module names.
	* gfortran.dg/submodule_5.f08: The same.
	* gfortran.dg/submodule_9.f08: The same.
	* gfortran.dg/submodule_10.f08: New test

From-SVN: r226622
parent 8282c877
2015-08-05 Paul Thomas <pault@gcc.gnu.org>
PR fortran/52846
* module.c (check_access): Return true if new static flag
'dump_smod' is true..
(gfc_dump_module): Rename original 'dump_module' and call from
new version. Use 'dump_smod' rather than the stack state to
determine if a submodule is being processed. The new version of
this procedure sets 'dump_smod' depending on the stack state and
then writes both the mod and smod files if a module is being
processed or just the smod for a submodule.
(gfc_use_module): Eliminate the check for module_name and
submodule_name being the same.
* trans-decl.c (gfc_finish_var_decl, gfc_build_qualified_array,
get_proc_pointer_decl): Set TREE_PUBLIC unconditionally and use
the conditions to set DECL_VISIBILITY as hidden and to set as
true DECL_VISIBILITY_SPECIFIED.
2015-08-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> 2015-08-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/64022 PR fortran/64022
......
...@@ -525,9 +525,9 @@ gfc_match_use (void) ...@@ -525,9 +525,9 @@ gfc_match_use (void)
gfc_intrinsic_op op; gfc_intrinsic_op op;
match m; match m;
gfc_use_list *use_list; gfc_use_list *use_list;
use_list = gfc_get_use_list (); use_list = gfc_get_use_list ();
if (gfc_match (" , ") == MATCH_YES) if (gfc_match (" , ") == MATCH_YES)
{ {
if ((m = gfc_match (" %n ::", module_nature)) == MATCH_YES) if ((m = gfc_match (" %n ::", module_nature)) == MATCH_YES)
...@@ -1080,7 +1080,7 @@ gzopen_included_file_1 (const char *name, gfc_directorylist *list, ...@@ -1080,7 +1080,7 @@ gzopen_included_file_1 (const char *name, gfc_directorylist *list,
return NULL; return NULL;
} }
static gzFile static gzFile
gzopen_included_file (const char *name, bool include_cwd, bool module) gzopen_included_file (const char *name, bool include_cwd, bool module)
{ {
gzFile f = NULL; gzFile f = NULL;
...@@ -1660,7 +1660,7 @@ write_atom (atom_type atom, const void *v) ...@@ -1660,7 +1660,7 @@ write_atom (atom_type atom, const void *v)
} }
if(p == NULL || *p == '\0') if(p == NULL || *p == '\0')
len = 0; len = 0;
else else
len = strlen (p); len = strlen (p);
...@@ -1856,7 +1856,7 @@ unquote_string (const char *s) ...@@ -1856,7 +1856,7 @@ unquote_string (const char *s)
{ {
if (*p != '\\') if (*p != '\\')
continue; continue;
if (p[1] == '\\') if (p[1] == '\\')
p++; p++;
else if (p[1] == 'U') else if (p[1] == 'U')
...@@ -2106,7 +2106,7 @@ mio_symbol_attribute (symbol_attribute *attr) ...@@ -2106,7 +2106,7 @@ mio_symbol_attribute (symbol_attribute *attr)
attr->proc = MIO_NAME (procedure_type) (attr->proc, procedures); attr->proc = MIO_NAME (procedure_type) (attr->proc, procedures);
attr->if_source = MIO_NAME (ifsrc) (attr->if_source, ifsrc_types); attr->if_source = MIO_NAME (ifsrc) (attr->if_source, ifsrc_types);
attr->save = MIO_NAME (save_state) (attr->save, save_status); attr->save = MIO_NAME (save_state) (attr->save, save_status);
ext_attr = attr->ext_attr; ext_attr = attr->ext_attr;
mio_integer ((int *) &ext_attr); mio_integer ((int *) &ext_attr);
attr->ext_attr = ext_attr; attr->ext_attr = ext_attr;
...@@ -2472,7 +2472,7 @@ mio_typespec (gfc_typespec *ts) ...@@ -2472,7 +2472,7 @@ mio_typespec (gfc_typespec *ts)
/* Add info for C interop and is_iso_c. */ /* Add info for C interop and is_iso_c. */
mio_integer (&ts->is_c_interop); mio_integer (&ts->is_c_interop);
mio_integer (&ts->is_iso_c); mio_integer (&ts->is_iso_c);
/* If the typespec is for an identifier either from iso_c_binding, or /* If the typespec is for an identifier either from iso_c_binding, or
a constant that was initialized to an identifier from it, use the a constant that was initialized to an identifier from it, use the
f90_type. Otherwise, use the ts->type, since it shouldn't matter. */ f90_type. Otherwise, use the ts->type, since it shouldn't matter. */
...@@ -2725,7 +2725,7 @@ mio_component (gfc_component *c, int vtype) ...@@ -2725,7 +2725,7 @@ mio_component (gfc_component *c, int vtype)
mio_symbol_attribute (&c->attr); mio_symbol_attribute (&c->attr);
if (c->ts.type == BT_CLASS) if (c->ts.type == BT_CLASS)
c->attr.class_ok = 1; c->attr.class_ok = 1;
c->attr.access = MIO_NAME (gfc_access) (c->attr.access, access_types); c->attr.access = MIO_NAME (gfc_access) (c->attr.access, access_types);
if (!vtype || strcmp (c->name, "_final") == 0 if (!vtype || strcmp (c->name, "_final") == 0
|| strcmp (c->name, "_hash") == 0) || strcmp (c->name, "_hash") == 0)
...@@ -2925,7 +2925,7 @@ mio_symtree_ref (gfc_symtree **stp) ...@@ -2925,7 +2925,7 @@ mio_symtree_ref (gfc_symtree **stp)
resolve_fixups (p->fixup, p->u.rsym.sym); resolve_fixups (p->fixup, p->u.rsym.sym);
p->fixup = NULL; p->fixup = NULL;
} }
if (p->type == P_UNKNOWN) if (p->type == P_UNKNOWN)
p->type = P_SYMBOL; p->type = P_SYMBOL;
...@@ -3260,7 +3260,7 @@ static const mstring intrinsics[] = ...@@ -3260,7 +3260,7 @@ static const mstring intrinsics[] =
/* Remedy a couple of situations where the gfc_expr's can be defective. */ /* Remedy a couple of situations where the gfc_expr's can be defective. */
static void static void
fix_mio_expr (gfc_expr *e) fix_mio_expr (gfc_expr *e)
{ {
...@@ -3830,7 +3830,7 @@ mio_full_typebound_tree (gfc_symtree** root) ...@@ -3830,7 +3830,7 @@ mio_full_typebound_tree (gfc_symtree** root)
{ {
gfc_symtree* st; gfc_symtree* st;
mio_lparen (); mio_lparen ();
require_atom (ATOM_STRING); require_atom (ATOM_STRING);
st = gfc_get_tbp_symtree (root, atom_string); st = gfc_get_tbp_symtree (root, atom_string);
...@@ -3931,7 +3931,7 @@ static void ...@@ -3931,7 +3931,7 @@ static void
mio_full_f2k_derived (gfc_symbol *sym) mio_full_f2k_derived (gfc_symbol *sym)
{ {
mio_lparen (); mio_lparen ();
if (iomode == IO_OUTPUT) if (iomode == IO_OUTPUT)
{ {
if (sym->f2k_derived) if (sym->f2k_derived)
...@@ -4158,7 +4158,7 @@ static void ...@@ -4158,7 +4158,7 @@ static void
mio_symbol (gfc_symbol *sym) mio_symbol (gfc_symbol *sym)
{ {
int intmod = INTMOD_NONE; int intmod = INTMOD_NONE;
mio_lparen (); mio_lparen ();
mio_symbol_attribute (&sym->attr); mio_symbol_attribute (&sym->attr);
...@@ -4219,7 +4219,7 @@ mio_symbol (gfc_symbol *sym) ...@@ -4219,7 +4219,7 @@ mio_symbol (gfc_symbol *sym)
else else
sym->from_intmod = (intmod_id) intmod; sym->from_intmod = (intmod_id) intmod;
} }
mio_integer (&(sym->intmod_sym_id)); mio_integer (&(sym->intmod_sym_id));
if (sym->attr.flavor == FL_DERIVED) if (sym->attr.flavor == FL_DERIVED)
...@@ -4559,7 +4559,7 @@ load_commons (void) ...@@ -4559,7 +4559,7 @@ load_commons (void)
if (strlen (label)) if (strlen (label))
p->binding_label = IDENTIFIER_POINTER (get_identifier (label)); p->binding_label = IDENTIFIER_POINTER (get_identifier (label));
XDELETEVEC (label); XDELETEVEC (label);
mio_rparen (); mio_rparen ();
} }
...@@ -4805,7 +4805,7 @@ load_needed (pointer_info *p) ...@@ -4805,7 +4805,7 @@ load_needed (pointer_info *p)
sym->name = dt_lower_string (p->u.rsym.true_name); sym->name = dt_lower_string (p->u.rsym.true_name);
sym->module = gfc_get_string (p->u.rsym.module); sym->module = gfc_get_string (p->u.rsym.module);
if (p->u.rsym.binding_label) if (p->u.rsym.binding_label)
sym->binding_label = IDENTIFIER_POINTER (get_identifier sym->binding_label = IDENTIFIER_POINTER (get_identifier
(p->u.rsym.binding_label)); (p->u.rsym.binding_label));
associate_integer_pointer (p, sym); associate_integer_pointer (p, sym);
...@@ -4989,7 +4989,7 @@ read_module (void) ...@@ -4989,7 +4989,7 @@ read_module (void)
info->u.rsym.binding_label = bind_label; info->u.rsym.binding_label = bind_label;
else else
XDELETEVEC (bind_label); XDELETEVEC (bind_label);
require_atom (ATOM_INTEGER); require_atom (ATOM_INTEGER);
info->u.rsym.ns = atom_int; info->u.rsym.ns = atom_int;
...@@ -5165,8 +5165,8 @@ read_module (void) ...@@ -5165,8 +5165,8 @@ read_module (void)
sym->module = gfc_get_string (info->u.rsym.module); sym->module = gfc_get_string (info->u.rsym.module);
if (info->u.rsym.binding_label) if (info->u.rsym.binding_label)
sym->binding_label = sym->binding_label =
IDENTIFIER_POINTER (get_identifier IDENTIFIER_POINTER (get_identifier
(info->u.rsym.binding_label)); (info->u.rsym.binding_label));
} }
...@@ -5279,13 +5279,18 @@ read_module (void) ...@@ -5279,13 +5279,18 @@ read_module (void)
/* Given an access type that is specific to an entity and the default /* Given an access type that is specific to an entity and the default
access, return nonzero if the entity is publicly accessible. If the access, return nonzero if the entity is publicly accessible. If the
element is declared as PUBLIC, then it is public; if declared element is declared as PUBLIC, then it is public; if declared
PRIVATE, then private, and otherwise it is public unless the default PRIVATE, then private, and otherwise it is public unless the default
access in this context has been declared PRIVATE. */ access in this context has been declared PRIVATE. */
static bool dump_smod = false;
static bool static bool
check_access (gfc_access specific_access, gfc_access default_access) check_access (gfc_access specific_access, gfc_access default_access)
{ {
if (dump_smod)
return true;
if (specific_access == ACCESS_PUBLIC) if (specific_access == ACCESS_PUBLIC)
return TRUE; return TRUE;
if (specific_access == ACCESS_PRIVATE) if (specific_access == ACCESS_PRIVATE)
...@@ -5359,7 +5364,7 @@ write_common_0 (gfc_symtree *st, bool this_module) ...@@ -5359,7 +5364,7 @@ write_common_0 (gfc_symtree *st, bool this_module)
const char *label; const char *label;
struct written_common *w; struct written_common *w;
bool write_me = true; bool write_me = true;
if (st == NULL) if (st == NULL)
return; return;
...@@ -5436,8 +5441,8 @@ write_blank_common (void) ...@@ -5436,8 +5441,8 @@ write_blank_common (void)
const char * name = BLANK_COMMON_NAME; const char * name = BLANK_COMMON_NAME;
int saved; int saved;
/* TODO: Blank commons are not bind(c). The F2003 standard probably says /* TODO: Blank commons are not bind(c). The F2003 standard probably says
this, but it hasn't been checked. Just making it so for now. */ this, but it hasn't been checked. Just making it so for now. */
int is_bind_c = 0; int is_bind_c = 0;
if (gfc_current_ns->blank_common.head == NULL) if (gfc_current_ns->blank_common.head == NULL)
return; return;
...@@ -5697,8 +5702,8 @@ find_symbols_to_write(sorted_pointer_info **tree, pointer_info *p) ...@@ -5697,8 +5702,8 @@ find_symbols_to_write(sorted_pointer_info **tree, pointer_info *p)
if (p->type == P_SYMBOL && p->u.wsym.state == NEEDS_WRITE) if (p->type == P_SYMBOL && p->u.wsym.state == NEEDS_WRITE)
{ {
sorted_pointer_info *sp = gfc_get_sorted_pointer_info(); sorted_pointer_info *sp = gfc_get_sorted_pointer_info();
sp->p = p; sp->p = p;
gfc_insert_bbt (tree, sp, compare_sorted_pointer_info); gfc_insert_bbt (tree, sp, compare_sorted_pointer_info);
} }
...@@ -5724,7 +5729,7 @@ write_symbol1_recursion (sorted_pointer_info *sp) ...@@ -5724,7 +5729,7 @@ write_symbol1_recursion (sorted_pointer_info *sp)
p1->u.wsym.state = WRITTEN; p1->u.wsym.state = WRITTEN;
write_symbol (p1->integer, p1->u.wsym.sym); write_symbol (p1->integer, p1->u.wsym.sym);
p1->u.wsym.sym->attr.public_used = 1; p1->u.wsym.sym->attr.public_used = 1;
write_symbol1_recursion (sp->right); write_symbol1_recursion (sp->right);
} }
...@@ -5945,10 +5950,10 @@ read_crc32_from_module_file (const char* filename, uLong* crc) ...@@ -5945,10 +5950,10 @@ read_crc32_from_module_file (const char* filename, uLong* crc)
/* Close the file. */ /* Close the file. */
fclose (file); fclose (file);
val = (buf[0] & 0xFF) + ((buf[1] & 0xFF) << 8) + ((buf[2] & 0xFF) << 16) val = (buf[0] & 0xFF) + ((buf[1] & 0xFF) << 8) + ((buf[2] & 0xFF) << 16)
+ ((buf[3] & 0xFF) << 24); + ((buf[3] & 0xFF) << 24);
*crc = val; *crc = val;
/* For debugging, the CRC value printed in hexadecimal should match /* For debugging, the CRC value printed in hexadecimal should match
the CRC printed by "zcat -l -v filename". the CRC printed by "zcat -l -v filename".
printf("CRC of file %s is %x\n", filename, val); */ printf("CRC of file %s is %x\n", filename, val); */
...@@ -5961,8 +5966,8 @@ read_crc32_from_module_file (const char* filename, uLong* crc) ...@@ -5961,8 +5966,8 @@ read_crc32_from_module_file (const char* filename, uLong* crc)
processing the module, dump_flag will be set to zero and we delete processing the module, dump_flag will be set to zero and we delete
the module file, even if it was already there. */ the module file, even if it was already there. */
void static void
gfc_dump_module (const char *name, int dump_flag) dump_module (const char *name, int dump_flag)
{ {
int n; int n;
char *filename, *filename_tmp; char *filename, *filename_tmp;
...@@ -5970,13 +5975,13 @@ gfc_dump_module (const char *name, int dump_flag) ...@@ -5970,13 +5975,13 @@ gfc_dump_module (const char *name, int dump_flag)
module_name = gfc_get_string (name); module_name = gfc_get_string (name);
if (gfc_state_stack->state == COMP_SUBMODULE) if (dump_smod)
{ {
name = submodule_name; name = submodule_name;
n = strlen (name) + strlen (SUBMODULE_EXTENSION) + 1; n = strlen (name) + strlen (SUBMODULE_EXTENSION) + 1;
} }
else else
n = strlen (name) + strlen (MODULE_EXTENSION) + 1; n = strlen (name) + strlen (MODULE_EXTENSION) + 1;
if (gfc_option.module_dir != NULL) if (gfc_option.module_dir != NULL)
{ {
...@@ -5991,7 +5996,7 @@ gfc_dump_module (const char *name, int dump_flag) ...@@ -5991,7 +5996,7 @@ gfc_dump_module (const char *name, int dump_flag)
strcpy (filename, name); strcpy (filename, name);
} }
if (gfc_state_stack->state == COMP_SUBMODULE) if (dump_smod)
strcat (filename, SUBMODULE_EXTENSION); strcat (filename, SUBMODULE_EXTENSION);
else else
strcat (filename, MODULE_EXTENSION); strcat (filename, MODULE_EXTENSION);
...@@ -6060,6 +6065,27 @@ gfc_dump_module (const char *name, int dump_flag) ...@@ -6060,6 +6065,27 @@ gfc_dump_module (const char *name, int dump_flag)
} }
void
gfc_dump_module (const char *name, int dump_flag)
{
if (gfc_state_stack->state == COMP_SUBMODULE)
dump_smod = true;
else
dump_smod =false;
dump_module (name, dump_flag);
if (dump_smod)
return;
/* Write a submodule file from a module. The 'dump_smod' flag switches
off the check for PRIVATE entities. */
dump_smod = true;
submodule_name = module_name;
dump_module (name, dump_flag);
dump_smod = false;
}
static void static void
create_intrinsic_function (const char *name, int id, create_intrinsic_function (const char *name, int id,
const char *modname, intmod_id module, const char *modname, intmod_id module,
...@@ -6140,7 +6166,7 @@ import_iso_c_binding_module (void) ...@@ -6140,7 +6166,7 @@ import_iso_c_binding_module (void)
/* symtree doesn't already exist in current namespace. */ /* symtree doesn't already exist in current namespace. */
gfc_get_sym_tree (iso_c_module_name, gfc_current_ns, &mod_symtree, gfc_get_sym_tree (iso_c_module_name, gfc_current_ns, &mod_symtree,
false); false);
if (mod_symtree != NULL) if (mod_symtree != NULL)
mod_sym = mod_symtree->n.sym; mod_sym = mod_symtree->n.sym;
else else
...@@ -6452,7 +6478,7 @@ create_int_parameter_array (const char *name, int size, gfc_expr *value, ...@@ -6452,7 +6478,7 @@ create_int_parameter_array (const char *name, int size, gfc_expr *value,
sym->as->rank = 1; sym->as->rank = 1;
sym->as->type = AS_EXPLICIT; sym->as->type = AS_EXPLICIT;
sym->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1); sym->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
sym->as->upper[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, size); sym->as->upper[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, size);
sym->value = value; sym->value = value;
sym->value->shape = gfc_get_shape (1); sym->value->shape = gfc_get_shape (1);
...@@ -6754,13 +6780,12 @@ gfc_use_module (gfc_use_list *module) ...@@ -6754,13 +6780,12 @@ gfc_use_module (gfc_use_list *module)
"USE statement at %C has no ONLY qualifier"); "USE statement at %C has no ONLY qualifier");
if (gfc_state_stack->state == COMP_MODULE if (gfc_state_stack->state == COMP_MODULE
|| module->submodule_name == NULL || module->submodule_name == NULL)
|| strcmp (module_name, module->submodule_name) == 0)
{ {
filename = XALLOCAVEC (char, strlen (module_name) filename = XALLOCAVEC (char, strlen (module_name)
+ strlen (MODULE_EXTENSION) + 1); + strlen (MODULE_EXTENSION) + 1);
strcpy (filename, module_name); strcpy (filename, module_name);
strcat (filename, MODULE_EXTENSION); strcat (filename, MODULE_EXTENSION);
} }
else else
{ {
...@@ -7003,7 +7028,7 @@ gfc_use_modules (void) ...@@ -7003,7 +7028,7 @@ gfc_use_modules (void)
r->next = next->rename; r->next = next->rename;
next->rename = seek->rename; next->rename = seek->rename;
} }
last->next = seek->next; last->next = seek->next;
free (seek); free (seek);
} }
else else
......
...@@ -596,6 +596,11 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym) ...@@ -596,6 +596,11 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
both, of course.) (J3/04-007, section 15.3). */ both, of course.) (J3/04-007, section 15.3). */
TREE_PUBLIC(decl) = 1; TREE_PUBLIC(decl) = 1;
DECL_COMMON(decl) = 1; DECL_COMMON(decl) = 1;
if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
{
DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (decl) = true;
}
} }
/* If a variable is USE associated, it's always external. */ /* If a variable is USE associated, it's always external. */
...@@ -609,9 +614,13 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym) ...@@ -609,9 +614,13 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
/* TODO: Don't set sym->module for result or dummy variables. */ /* TODO: Don't set sym->module for result or dummy variables. */
gcc_assert (current_function_decl == NULL_TREE || sym->result == sym); gcc_assert (current_function_decl == NULL_TREE || sym->result == sym);
if (sym->attr.access != ACCESS_PRIVATE || sym->attr.public_used) TREE_PUBLIC (decl) = 1;
TREE_PUBLIC (decl) = 1;
TREE_STATIC (decl) = 1; TREE_STATIC (decl) = 1;
if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
{
DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (decl) = true;
}
} }
/* Derived types are a bit peculiar because of the possibility of /* Derived types are a bit peculiar because of the possibility of
...@@ -837,9 +846,13 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym) ...@@ -837,9 +846,13 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
else else
TREE_STATIC (token) = 1; TREE_STATIC (token) = 1;
if (sym->attr.use_assoc || sym->attr.access != ACCESS_PRIVATE || TREE_PUBLIC (token) = 1;
sym->attr.public_used)
TREE_PUBLIC (token) = 1; if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
{
DECL_VISIBILITY (token) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (token) = true;
}
} }
else else
{ {
...@@ -1747,9 +1760,12 @@ get_proc_pointer_decl (gfc_symbol *sym) ...@@ -1747,9 +1760,12 @@ get_proc_pointer_decl (gfc_symbol *sym)
else if (sym->module && sym->ns->proc_name->attr.flavor == FL_MODULE) else if (sym->module && sym->ns->proc_name->attr.flavor == FL_MODULE)
{ {
/* This is the declaration of a module variable. */ /* This is the declaration of a module variable. */
if (sym->ns->proc_name->attr.flavor == FL_MODULE TREE_PUBLIC (decl) = 1;
&& (sym->attr.access != ACCESS_PRIVATE || sym->attr.public_used)) if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
TREE_PUBLIC (decl) = 1; {
DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (decl) = true;
}
TREE_STATIC (decl) = 1; TREE_STATIC (decl) = 1;
} }
......
2015-08-05 Paul Thomas <pault@gcc.gnu.org>
PR fortran/52846
* lib/fortran-modules.exp: Call cleanup-submodules from
cleanup-modules.
* gfortran.dg/public_private_module_2.f90: Add two XFAILS to
cover the cases where private entities are no longer optimized
away.
* gfortran.dg/public_private_module_6.f90: Add an XFAIL for the
same reason.
* gfortran.dg/submodule_1.f08: Change cleanup module names.
* gfortran.dg/submodule_5.f08: The same.
* gfortran.dg/submodule_9.f08: The same.
* gfortran.dg/submodule_10.f08: New test.
2015-08-05 Paolo Carlini <paolo.carlini@oracle.com> 2015-08-05 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/66595 PR c++/66595
......
...@@ -18,12 +18,15 @@ ...@@ -18,12 +18,15 @@
integer, bind(C,name='') :: qq integer, bind(C,name='') :: qq
end module mod end module mod
! The two xfails below have appeared with the introduction of submodules. 'iii' and
! 'mmm' now are TREE_PUBLIC but has DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN set.
! { dg-final { scan-assembler "__mod_MOD_aa" } } ! { dg-final { scan-assembler "__mod_MOD_aa" } }
! { dg-final { scan-assembler-not "iii" } } ! { dg-final { scan-assembler-not "iii" { xfail *-*-* } } }
! { dg-final { scan-assembler "jj" } } ! { dg-final { scan-assembler "jj" } }
! { dg-final { scan-assembler "lll" } } ! { dg-final { scan-assembler "lll" } }
! { dg-final { scan-assembler-not "kk" } } ! { dg-final { scan-assembler-not "kk" } }
! { dg-final { scan-assembler-not "mmmm" } } ! { dg-final { scan-assembler-not "mmmm" { xfail *-*-* } } }
! { dg-final { scan-assembler "nnn" } } ! { dg-final { scan-assembler "nnn" } }
! { dg-final { scan-assembler "oo" } } ! { dg-final { scan-assembler "oo" } }
! { dg-final { scan-assembler "__mod_MOD_qq" } } ! { dg-final { scan-assembler "__mod_MOD_qq" } }
......
...@@ -11,4 +11,7 @@ module m ...@@ -11,4 +11,7 @@ module m
integer, save :: aaaa integer, save :: aaaa
end module m end module m
! { dg-final { scan-assembler-not "aaaa" } } ! The xfail below has appeared with the introduction of submodules. 'aaaa'
! now is TREE_PUBLIC but has DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN set.
! { dg-final { scan-assembler-not "aaaa" { xfail *-*-* } } }
...@@ -170,6 +170,6 @@ ...@@ -170,6 +170,6 @@
message2 = "" message2 = ""
end subroutine end subroutine
end program end program
! { dg-final { cleanup-submodules "foo_interface_son" } } ! { dg-final { cleanup-submodules "foo_interface@foo_interface_son" } }
! { dg-final { cleanup-submodules "foo_interface_grandson" } } ! { dg-final { cleanup-submodules "foo_interface@foo_interface_grandson" } }
! { dg-final { cleanup-submodules "foo_interface_daughter" } } ! { dg-final { cleanup-submodules "foo_interface@foo_interface_daughter" } }
! { dg-do compile }
!
! Checks that PRIVATE enities are visible to submodules.
!
! Contributed by Salvatore Filippone <salvatore.filippone@uniroma2.it>
!
module const_mod
integer, parameter :: ndig=8
integer, parameter :: ipk_ = selected_int_kind(ndig)
integer, parameter :: longndig=12
integer, parameter :: long_int_k_ = selected_int_kind(longndig)
integer, parameter :: mpik_ = kind(1)
integer(ipk_), parameter, public :: success_=0
end module const_mod
module error_mod
use const_mod
integer(ipk_), parameter, public :: act_ret_=0
integer(ipk_), parameter, public :: act_print_=1
integer(ipk_), parameter, public :: act_abort_=2
integer(ipk_), parameter, public :: no_err_ = 0
public error, errcomm, get_numerr, &
& error_handler, &
& ser_error_handler, par_error_handler
interface error_handler
module subroutine ser_error_handler(err_act)
integer(ipk_), intent(inout) :: err_act
end subroutine ser_error_handler
module subroutine par_error_handler(ictxt,err_act)
integer(mpik_), intent(in) :: ictxt
integer(ipk_), intent(in) :: err_act
end subroutine par_error_handler
end interface
interface error
module subroutine serror()
end subroutine serror
module subroutine perror(ictxt,abrt)
integer(mpik_), intent(in) :: ictxt
logical, intent(in), optional :: abrt
end subroutine perror
end interface
interface error_print_stack
module subroutine par_error_print_stack(ictxt)
integer(mpik_), intent(in) :: ictxt
end subroutine par_error_print_stack
module subroutine ser_error_print_stack()
end subroutine ser_error_print_stack
end interface
interface errcomm
module subroutine errcomm(ictxt, err)
integer(mpik_), intent(in) :: ictxt
integer(ipk_), intent(inout):: err
end subroutine errcomm
end interface errcomm
private
type errstack_node
integer(ipk_) :: err_code=0
character(len=20) :: routine=''
integer(ipk_),dimension(5) :: i_err_data=0
character(len=40) :: a_err_data=''
type(errstack_node), pointer :: next
end type errstack_node
type errstack
type(errstack_node), pointer :: top => null()
integer(ipk_) :: n_elems=0
end type errstack
type(errstack), save :: error_stack
integer(ipk_), save :: error_status = no_err_
integer(ipk_), save :: verbosity_level = 1
integer(ipk_), save :: err_action = act_abort_
integer(ipk_), save :: debug_level = 0, debug_unit, serial_debug_level=0
contains
end module error_mod
submodule (error_mod) error_impl_mod
use const_mod
contains
! checks whether an error has occurred on one of the processes in the execution pool
subroutine errcomm(ictxt, err)
integer(mpik_), intent(in) :: ictxt
integer(ipk_), intent(inout):: err
end subroutine errcomm
subroutine ser_error_handler(err_act)
implicit none
integer(ipk_), intent(inout) :: err_act
if (err_act /= act_ret_) &
& call error()
if (err_act == act_abort_) stop
return
end subroutine ser_error_handler
subroutine par_error_handler(ictxt,err_act)
implicit none
integer(mpik_), intent(in) :: ictxt
integer(ipk_), intent(in) :: err_act
if (err_act == act_print_) &
& call error(ictxt, abrt=.false.)
if (err_act == act_abort_) &
& call error(ictxt, abrt=.true.)
return
end subroutine par_error_handler
subroutine par_error_print_stack(ictxt)
integer(mpik_), intent(in) :: ictxt
call error(ictxt, abrt=.false.)
end subroutine par_error_print_stack
subroutine ser_error_print_stack()
call error()
end subroutine ser_error_print_stack
subroutine serror()
implicit none
end subroutine serror
subroutine perror(ictxt,abrt)
use const_mod
implicit none
integer(mpik_), intent(in) :: ictxt
logical, intent(in), optional :: abrt
end subroutine perror
end submodule error_impl_mod
program testlk
use error_mod
implicit none
call error()
stop
end program testlk
! { dg-final { cleanup-submodules "error_mod@error_impl_mod" } }
...@@ -49,3 +49,4 @@ contains ...@@ -49,3 +49,4 @@ contains
end SUBMODULE foo_interface_daughter end SUBMODULE foo_interface_daughter
end end
! { dg-final { cleanup-submodules "foo_interface@foo_interface_daughter" } }
...@@ -38,3 +38,4 @@ program a_s ...@@ -38,3 +38,4 @@ program a_s
implicit none implicit none
call p() call p()
end program end program
! { dg-final { cleanup-submodules "mod_a@b" } }
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
# helper to deal with fortran modules # helper to deal with fortran modules
# Remove files for specified Fortran modules. # Remove files for specified Fortran modules.
# This includes both .mod and .smod files.
proc cleanup-modules { modlist } { proc cleanup-modules { modlist } {
global clean global clean
foreach mod [concat $modlist $clean] { foreach mod [concat $modlist $clean] {
...@@ -27,6 +28,7 @@ proc cleanup-modules { modlist } { ...@@ -27,6 +28,7 @@ proc cleanup-modules { modlist } {
} }
remote_file build delete $m remote_file build delete $m
} }
cleanup-submodules $modlist
} }
# Remove files for specified Fortran submodules. # Remove files for specified Fortran submodules.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment