goto conflict_std;\
}
-static bool
-check_conflict (symbol_attribute *attr, const char *name, locus *where)
+bool
+gfc_check_conflict (symbol_attribute *attr, const char *name, locus *where)
{
static const char *dummy = "DUMMY", *save = "SAVE", *pointer = "POINTER",
*target = "TARGET", *external = "EXTERNAL", *intent = "INTENT",
conf (allocatable, elemental);
conf (in_common, automatic);
- conf (in_equivalence, automatic);
conf (result, automatic);
conf (use_assoc, automatic);
conf (dummy, automatic);
if (check_used (attr, NULL, where))
return false;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
}
attr->allocatable = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
return false;
attr->automatic = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
}
attr->codimension = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
}
attr->dimension = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return false;
attr->contiguous = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
attr->external = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
attr->intrinsic = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
}
attr->optional = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
bool
}
attr->pdt_kind = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
bool
}
attr->pdt_len = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
else
attr->pointer = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
return false;
attr->cray_pointer = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
}
attr->cray_pointee = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
}
attr->is_protected = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return false;
attr->result = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
}
attr->save = s;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
}
attr->value = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
attr->volatile_ = 1;
attr->volatile_ns = gfc_current_ns;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
attr->asynchronous = 1;
attr->asynchronous_ns = gfc_current_ns;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
}
attr->threadprivate = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return true;
attr->omp_declare_target = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return true;
attr->omp_declare_target_link = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return true;
attr->oacc_declare_create = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return true;
attr->oacc_declare_copyin = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return true;
attr->oacc_declare_deviceptr = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return true;
attr->oacc_declare_device_resident = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
}
attr->target = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
/* Duplicate dummy arguments are allowed due to ENTRY statements. */
attr->dummy = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
/* Duplicate attribute already checked for. */
attr->in_common = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
/* Duplicate attribute already checked for. */
attr->in_equivalence = 1;
- if (!check_conflict (attr, name, where))
+ if (!gfc_check_conflict (attr, name, where))
return false;
if (attr->flavor == FL_VARIABLE)
return false;
attr->data = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
{
attr->in_namelist = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return false;
attr->sequence = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
}
attr->elemental = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
}
attr->pure = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
}
attr->recursive = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
}
attr->entry = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return false;
attr->function = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
compiler-generated), do not check. See PR 84394. */
if (name && *name != '_' && gfc_current_state () != COMP_BLOCK_DATA)
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
else
return true;
}
return false;
attr->generic = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
attr->procedure = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
attr->abstract = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
attr->flavor = f;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
|| attr->dimension))
return false;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
if (attr->intent == INTENT_UNKNOWN)
{
attr->intent = intent;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
if (where == NULL)
|| (attr->use_assoc && attr->access != ACCESS_PRIVATE))
{
attr->access = access;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
if (where == NULL)
if (!gfc_notify_std (GFC_STD_F2003, "BIND(C) at %L", where))
return false;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
return;
if (sym->attr.in_common
+ || sym->attr.in_equivalence
|| sym->attr.dummy
|| sym->attr.result
|| sym->attr.flavor != FL_VARIABLE)
/* Get storage for local equivalence. */
static tree
-build_equiv_decl (tree union_type, bool is_init, bool is_saved)
+build_equiv_decl (tree union_type, bool is_init, bool is_saved, bool is_auto)
{
tree decl;
char name[18];
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
- if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
- || is_saved)
+ if (!is_auto && (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
+ || is_saved))
TREE_STATIC (decl) = 1;
TREE_ADDRESSABLE (decl) = 1;
tree decl;
bool is_init = false;
bool is_saved = false;
+ bool is_auto = false;
/* Declare the variables inside the common block.
If the current common block contains any equivalence object, then
/* Has SAVE attribute. */
if (s->sym->attr.save)
is_saved = true;
+
+ /* Has AUTOMATIC attribute. */
+ if (s->sym->attr.automatic)
+ is_auto = true;
}
finish_record_layout (rli, true);
if (com)
decl = build_common_decl (com, union_type, is_init);
else
- decl = build_equiv_decl (union_type, is_init, is_saved);
+ decl = build_equiv_decl (union_type, is_init, is_saved, is_auto);
if (is_init)
{
confirm_condition (f, eq1, n, eq2);
}
+static void
+accumulate_equivalence_attributes (symbol_attribute *dummy_symbol, gfc_equiv *e)
+{
+ symbol_attribute attr = e->expr->symtree->n.sym->attr;
+
+ dummy_symbol->dummy |= attr.dummy;
+ dummy_symbol->pointer |= attr.pointer;
+ dummy_symbol->target |= attr.target;
+ dummy_symbol->external |= attr.external;
+ dummy_symbol->intrinsic |= attr.intrinsic;
+ dummy_symbol->allocatable |= attr.allocatable;
+ dummy_symbol->elemental |= attr.elemental;
+ dummy_symbol->recursive |= attr.recursive;
+ dummy_symbol->in_common |= attr.in_common;
+ dummy_symbol->result |= attr.result;
+ dummy_symbol->in_namelist |= attr.in_namelist;
+ dummy_symbol->optional |= attr.optional;
+ dummy_symbol->entry |= attr.entry;
+ dummy_symbol->function |= attr.function;
+ dummy_symbol->subroutine |= attr.subroutine;
+ dummy_symbol->dimension |= attr.dimension;
+ dummy_symbol->in_equivalence |= attr.in_equivalence;
+ dummy_symbol->use_assoc |= attr.use_assoc;
+ dummy_symbol->cray_pointer |= attr.cray_pointer;
+ dummy_symbol->cray_pointee |= attr.cray_pointee;
+ dummy_symbol->data |= attr.data;
+ dummy_symbol->value |= attr.value;
+ dummy_symbol->volatile_ |= attr.volatile_;
+ dummy_symbol->is_protected |= attr.is_protected;
+ dummy_symbol->is_bind_c |= attr.is_bind_c;
+ dummy_symbol->procedure |= attr.procedure;
+ dummy_symbol->proc_pointer |= attr.proc_pointer;
+ dummy_symbol->abstract |= attr.abstract;
+ dummy_symbol->asynchronous |= attr.asynchronous;
+ dummy_symbol->codimension |= attr.codimension;
+ dummy_symbol->contiguous |= attr.contiguous;
+ dummy_symbol->generic |= attr.generic;
+ dummy_symbol->automatic |= attr.automatic;
+ dummy_symbol->threadprivate |= attr.threadprivate;
+ dummy_symbol->omp_declare_target |= attr.omp_declare_target;
+ dummy_symbol->omp_declare_target_link |= attr.omp_declare_target_link;
+ dummy_symbol->oacc_declare_copyin |= attr.oacc_declare_copyin;
+ dummy_symbol->oacc_declare_create |= attr.oacc_declare_create;
+ dummy_symbol->oacc_declare_deviceptr |= attr.oacc_declare_deviceptr;
+ dummy_symbol->oacc_declare_device_resident
+ |= attr.oacc_declare_device_resident;
+
+ /* Not strictly correct, but probably close enough. */
+ if (attr.save > dummy_symbol->save)
+ dummy_symbol->save = attr.save;
+ if (attr.access > dummy_symbol->access)
+ dummy_symbol->access = attr.access;
+}
/* Given a segment element, search through the equivalence lists for unused
conditions that involve the symbol. Add these rules to the segment. */
eq = NULL;
/* Search the equivalence list, including the root (first) element
- for the symbol that owns the segment. */
+ for the symbol that owns the segment. */
+ symbol_attribute dummy_symbol;
+ memset (&dummy_symbol, 0, sizeof (dummy_symbol));
for (e2 = e1; e2; e2 = e2->eq)
{
+ accumulate_equivalence_attributes (&dummy_symbol, e2);
if (!e2->used && e2->expr->symtree->n.sym == n->sym)
{
eq = e2;
}
}
+ gfc_check_conflict (&dummy_symbol, e1->expr->symtree->name, &e1->expr->where);
+
/* Go to the next root element. */
if (eq == NULL)
continue;