+2007-05-06 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/32633
+ * symbol.c (save_status): New.
+ * gfortran.h (save_status): Added external declaration.
+ (check_conflict): Check for conflicting explicite SAVE statements
+ only.
+ (gen_special_c_interop_ptr): Use SAVE_EXPLICIT constant.
+ * module.c (ab_attribute, attr_bits): Removed enumerator value
+ AB_SAVE for save attribute.
+ (mio_symbol_attribute): Import/export the full SAVE status,
+ removed usage of AB_SAVE.
+ * dump-parse-tree.c (gfc_show_attr): Dump full SAVE status.
+ * decl.c (add_init_expr_to_sym): Set SAVE_IMPLICIT only if not
+ already explicit.
+
2007-07-05 Daniel Franke <franke.daniel@gmail.com>
Tobias Burnus <burnus@net-b.de>
}
sym->value = init;
- sym->attr.save = SAVE_IMPLICIT;
+ if (sym->attr.save == SAVE_NONE)
+ sym->attr.save = SAVE_IMPLICIT;
*initp = NULL;
}
gfc_show_attr (symbol_attribute *attr)
{
- gfc_status ("(%s %s %s %s", gfc_code2string (flavors, attr->flavor),
+ gfc_status ("(%s %s %s %s %s", gfc_code2string (flavors, attr->flavor),
gfc_intent_string (attr->intent),
gfc_code2string (access_types, attr->access),
- gfc_code2string (procedures, attr->proc));
+ gfc_code2string (procedures, attr->proc),
+ gfc_code2string (save_status, attr->save));
if (attr->allocatable)
gfc_status (" ALLOCATABLE");
gfc_status (" POINTER");
if (attr->protected)
gfc_status (" PROTECTED");
- if (attr->save)
- gfc_status (" SAVE");
if (attr->value)
gfc_status (" VALUE");
if (attr->volatile_)
extern const mstring intents[];
extern const mstring access_types[];
extern const mstring ifsrc_types[];
+extern const mstring save_status[];
/* Enumeration of all the generic intrinsic functions. Used by the
backend for identification of a function. */
typedef enum
{ AB_ALLOCATABLE, AB_DIMENSION, AB_EXTERNAL, AB_INTRINSIC, AB_OPTIONAL,
- AB_POINTER, AB_SAVE, AB_TARGET, AB_DUMMY, AB_RESULT, AB_DATA,
+ AB_POINTER, AB_TARGET, AB_DUMMY, AB_RESULT, AB_DATA,
AB_IN_NAMELIST, AB_IN_COMMON, AB_FUNCTION, AB_SUBROUTINE, AB_SEQUENCE,
AB_ELEMENTAL, AB_PURE, AB_RECURSIVE, AB_GENERIC, AB_ALWAYS_EXPLICIT,
AB_CRAY_POINTER, AB_CRAY_POINTEE, AB_THREADPRIVATE, AB_ALLOC_COMP,
minit ("INTRINSIC", AB_INTRINSIC),
minit ("OPTIONAL", AB_OPTIONAL),
minit ("POINTER", AB_POINTER),
- minit ("SAVE", AB_SAVE),
minit ("VOLATILE", AB_VOLATILE),
minit ("TARGET", AB_TARGET),
minit ("THREADPRIVATE", AB_THREADPRIVATE),
DECL_MIO_NAME (gfc_access)
DECL_MIO_NAME (gfc_intrinsic_op)
DECL_MIO_NAME (ifsrc)
+DECL_MIO_NAME (save_state)
DECL_MIO_NAME (procedure_type)
DECL_MIO_NAME (ref_type)
DECL_MIO_NAME (sym_flavor)
attr->intent = MIO_NAME (sym_intent) (attr->intent, intents);
attr->proc = MIO_NAME (procedure_type) (attr->proc, procedures);
attr->if_source = MIO_NAME (ifsrc) (attr->if_source, ifsrc_types);
+ attr->save = MIO_NAME (save_state) (attr->save, save_status);
if (iomode == IO_OUTPUT)
{
MIO_NAME (ab_attribute) (AB_POINTER, attr_bits);
if (attr->protected)
MIO_NAME (ab_attribute) (AB_PROTECTED, attr_bits);
- if (attr->save)
- MIO_NAME (ab_attribute) (AB_SAVE, attr_bits);
if (attr->value)
MIO_NAME (ab_attribute) (AB_VALUE, attr_bits);
if (attr->volatile_)
case AB_PROTECTED:
attr->protected = 1;
break;
- case AB_SAVE:
- attr->save = 1;
- break;
case AB_VALUE:
attr->value = 1;
break;
minit ("USAGE", IFSRC_USAGE)
};
+const mstring save_status[] =
+{
+ minit ("UNKNOWN", SAVE_NONE),
+ minit ("EXPLICIT-SAVE", SAVE_EXPLICIT),
+ minit ("IMPLICIT-SAVE", SAVE_IMPLICIT),
+};
/* This is to make sure the backend generates setup code in the correct
order. */
}
}
+ if (attr->save == SAVE_EXPLICIT)
+ {
+ conf (dummy, save);
+ conf (in_common, save);
+ conf (result, save);
+
+ switch (attr->flavor)
+ {
+ case FL_PROGRAM:
+ case FL_BLOCK_DATA:
+ case FL_MODULE:
+ case FL_LABEL:
+ case FL_PROCEDURE:
+ case FL_DERIVED:
+ case FL_PARAMETER:
+ a1 = gfc_code2string (flavors, attr->flavor);
+ a2 = save;
+ goto conflict;
+
+ case FL_VARIABLE:
+ case FL_NAMELIST:
+ default:
+ break;
+ }
+ }
+
conf (dummy, entry);
conf (dummy, intrinsic);
- conf (dummy, save);
conf (dummy, threadprivate);
conf (pointer, target);
conf (pointer, intrinsic);
conf (external, dimension); /* See Fortran 95's R504. */
conf (external, intrinsic);
-
+
if (attr->if_source || attr->contained)
{
conf (external, subroutine);
conf (in_common, dummy);
conf (in_common, allocatable);
conf (in_common, result);
- conf (in_common, save);
- conf (result, save);
conf (dummy, result);
case FL_LABEL:
conf2 (dimension);
conf2 (dummy);
- conf2 (save);
conf2 (volatile_);
conf2 (pointer);
conf2 (protected);
case FL_PROCEDURE:
conf2 (intent);
- conf2 (save);
if (attr->subroutine)
{
case PROC_DUMMY:
conf2 (result);
conf2 (in_common);
- conf2 (save);
conf2 (threadprivate);
break;
case FL_DERIVED:
conf2 (dummy);
- conf2 (save);
conf2 (pointer);
conf2 (target);
conf2 (external);
conf2 (target);
conf2 (dummy);
conf2 (in_common);
- conf2 (save);
conf2 (value);
conf2 (volatile_);
conf2 (threadprivate);
/* Set up the symbol's important fields. Save attr required so we can
initialize the ptr to NULL. */
- tmp_sym->attr.save = 1;
+ tmp_sym->attr.save = SAVE_EXPLICIT;
tmp_sym->ts.is_c_interop = 1;
tmp_sym->attr.is_c_interop = 1;
tmp_sym->ts.is_iso_c = 1;
+2007-07-06 Daniel Franke <franke.daniel@gmail.com>
+
+ * gfortran.dg/save_parameter.f90: New test.
+ * gfortran.dg/module_md5_1.f90: Updated MD5 sum.
+
2007-07-06 Richard Guenther <rguenther@suse.de>
* g++.dg/opt/pr30965.C: New testcase.
use foo
print *, pi
end program test
-! { dg-final { scan-module "foo" "MD5:6d026a84bb779a7b6789854d85d4f01f" } }
+! { dg-final { scan-module "foo" "MD5:1a6374d65e99c0175c42016a649f79db" } }
! { dg-final { cleanup-modules "foo" } }
--- /dev/null
+! { dg-do compile }
+! PR fortran/32633 - implied SAVE conflicts with parameter attribute
+! Testcase contributed by: Joost VandeVondele <jv244@cam.ac.uk>
+
+MODULE test
+ CHARACTER(len=1), PARAMETER :: backslash = '\\'
+ PUBLIC :: backslash
+END MODULE
+
+! { dg-final { cleanup-modules "test" } }