+2010-07-11 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/44689
+ * decl.c (build_sym,attr_decl1): Only build the class container if the
+ symbol has sufficient attributes.
+ * expr.c (gfc_check_pointer_assign): Use class_pointer instead of
+ pointer attribute for classes.
+ * match.c (gfc_match_allocate,gfc_match_deallocate): Ditto.
+ * module.c (MOD_VERSION): Bump.
+ (enum ab_attribute,attr_bits): Add AB_CLASS_POINTER.
+ (mio_symbol_attribute): Handle class_pointer attribute.
+ * parse.c (parse_derived): Use class_pointer instead of pointer
+ attribute for classes.
+ * primary.c (gfc_variable_attr,gfc_expr_attr): Ditto.
+ * resolve.c (resolve_structure_cons,resolve_deallocate_expr,
+ resolve_allocate_expr,resolve_fl_derived): Ditto.
+ (resolve_fl_var_and_proc): Check for class_ok attribute.
+
2010-07-10 Mikael Morin <mikael@gcc.gnu.org>
* trans-io.c (gfc_build_st_parameter): Update calls to
sym->attr.implied_index = 0;
- if (sym->ts.type == BT_CLASS)
- {
- sym->attr.class_ok = (sym->attr.dummy
- || sym->attr.pointer
- || sym->attr.allocatable) ? 1 : 0;
- gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as, false);
- }
+ if (sym->ts.type == BT_CLASS
+ && (sym->attr.class_ok = sym->attr.dummy || sym->attr.pointer
+ || sym->attr.allocatable))
+ gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as, false);
return SUCCESS;
}
/* Update symbol table. DIMENSION attribute is set in
gfc_set_array_spec(). For CLASS variables, this must be applied
to the first component, or '$data' field. */
- if (sym->ts.type == BT_CLASS)
+ if (sym->ts.type == BT_CLASS && sym->ts.u.derived->attr.is_class)
{
if (gfc_copy_attr (&CLASS_DATA (sym)->attr, ¤t_attr,&var_locus)
== FAILURE)
m = MATCH_ERROR;
goto cleanup;
}
- sym->attr.class_ok = (sym->attr.class_ok || current_attr.allocatable
- || current_attr.pointer);
}
else
{
goto cleanup;
}
}
+
+ if (sym->ts.type == BT_CLASS && !sym->attr.class_ok
+ && (sym->attr.class_ok = sym->attr.class_ok || current_attr.allocatable
+ || current_attr.pointer))
+ gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as, false);
if (gfc_set_array_spec (sym, as, &var_locus) == FAILURE)
{
}
if (!pointer && !proc_pointer
- && !(lvalue->ts.type == BT_CLASS && CLASS_DATA (lvalue)->attr.pointer))
+ && !(lvalue->ts.type == BT_CLASS
+ && CLASS_DATA (lvalue)->attr.class_pointer))
{
gfc_error ("Pointer assignment to non-POINTER at %L", &lvalue->where);
return FAILURE;
lvalue.where = sym->declared_at;
if (sym->attr.pointer || sym->attr.proc_pointer
- || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.pointer
+ || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.class_pointer
&& rvalue->expr_type == EXPR_NULL))
r = gfc_check_pointer_assign (&lvalue, rvalue);
else
|| tail->expr->ref->type == REF_ARRAY));
if (sym && sym->ts.type == BT_CLASS)
b2 = !(CLASS_DATA (sym)->attr.allocatable
- || CLASS_DATA (sym)->attr.pointer);
+ || CLASS_DATA (sym)->attr.class_pointer);
else
b2 = sym && !(sym->attr.allocatable || sym->attr.pointer
|| sym->attr.proc_pointer);
|| tail->expr->ref->type == REF_ARRAY));
if (sym && sym->ts.type == BT_CLASS)
b2 = !(CLASS_DATA (sym)->attr.allocatable
- || CLASS_DATA (sym)->attr.pointer);
+ || CLASS_DATA (sym)->attr.class_pointer);
else
b2 = sym && !(sym->attr.allocatable || sym->attr.pointer
|| sym->attr.proc_pointer);
/* Don't put any single quote (') in MOD_VERSION,
if yout want it to be recognized. */
-#define MOD_VERSION "5"
+#define MOD_VERSION "6"
/* Structure that describes a position within a module file. */
AB_POINTER_COMP, AB_PRIVATE_COMP, AB_VALUE, AB_VOLATILE, AB_PROTECTED,
AB_IS_BIND_C, AB_IS_C_INTEROP, AB_IS_ISO_C, AB_ABSTRACT, AB_ZERO_COMP,
AB_IS_CLASS, AB_PROCEDURE, AB_PROC_POINTER, AB_ASYNCHRONOUS, AB_CODIMENSION,
- AB_COARRAY_COMP, AB_VTYPE, AB_VTAB, AB_CONTIGUOUS
+ AB_COARRAY_COMP, AB_VTYPE, AB_VTAB, AB_CONTIGUOUS, AB_CLASS_POINTER
}
ab_attribute;
minit ("PROC_POINTER", AB_PROC_POINTER),
minit ("VTYPE", AB_VTYPE),
minit ("VTAB", AB_VTAB),
+ minit ("CLASS_POINTER", AB_CLASS_POINTER),
minit (NULL, -1)
};
MIO_NAME (ab_attribute) (AB_OPTIONAL, attr_bits);
if (attr->pointer)
MIO_NAME (ab_attribute) (AB_POINTER, attr_bits);
+ if (attr->class_pointer)
+ MIO_NAME (ab_attribute) (AB_CLASS_POINTER, attr_bits);
if (attr->is_protected)
MIO_NAME (ab_attribute) (AB_PROTECTED, attr_bits);
if (attr->value)
case AB_POINTER:
attr->pointer = 1;
break;
+ case AB_CLASS_POINTER:
+ attr->class_pointer = 1;
+ break;
case AB_PROTECTED:
attr->is_protected = 1;
break;
/* Look for pointer components. */
if (c->attr.pointer
- || (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.pointer)
+ || (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.class_pointer)
|| (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.pointer_comp))
sym->attr.pointer_comp = 1;
if (sym->ts.type == BT_CLASS)
{
dimension = CLASS_DATA (sym)->attr.dimension;
- pointer = CLASS_DATA (sym)->attr.pointer;
+ pointer = CLASS_DATA (sym)->attr.class_pointer;
allocatable = CLASS_DATA (sym)->attr.allocatable;
}
else
if (comp->ts.type == BT_CLASS)
{
- pointer = CLASS_DATA (comp)->attr.pointer;
+ pointer = CLASS_DATA (comp)->attr.class_pointer;
allocatable = CLASS_DATA (comp)->attr.allocatable;
}
else
if (sym->ts.type == BT_CLASS)
{
attr.dimension = CLASS_DATA (sym)->attr.dimension;
- attr.pointer = CLASS_DATA (sym)->attr.pointer;
+ attr.pointer = CLASS_DATA (sym)->attr.class_pointer;
attr.allocatable = CLASS_DATA (sym)->attr.allocatable;
}
}
&& !(comp->attr.pointer || comp->attr.allocatable
|| comp->attr.proc_pointer
|| (comp->ts.type == BT_CLASS
- && (CLASS_DATA (comp)->attr.pointer
+ && (CLASS_DATA (comp)->attr.class_pointer
|| CLASS_DATA (comp)->attr.allocatable))))
{
t = FAILURE;
if (sym->ts.type == BT_CLASS)
{
allocatable = CLASS_DATA (sym)->attr.allocatable;
- pointer = CLASS_DATA (sym)->attr.pointer;
+ pointer = CLASS_DATA (sym)->attr.class_pointer;
}
else
{
if (c->ts.type == BT_CLASS)
{
allocatable = CLASS_DATA (c)->attr.allocatable;
- pointer = CLASS_DATA (c)->attr.pointer;
+ pointer = CLASS_DATA (c)->attr.class_pointer;
}
else
{
if (sym->ts.type == BT_CLASS)
{
allocatable = CLASS_DATA (sym)->attr.allocatable;
- pointer = CLASS_DATA (sym)->attr.pointer;
+ pointer = CLASS_DATA (sym)->attr.class_pointer;
dimension = CLASS_DATA (sym)->attr.dimension;
codimension = CLASS_DATA (sym)->attr.codimension;
is_abstract = CLASS_DATA (sym)->attr.abstract;
if (c->ts.type == BT_CLASS)
{
allocatable = CLASS_DATA (c)->attr.allocatable;
- pointer = CLASS_DATA (c)->attr.pointer;
+ pointer = CLASS_DATA (c)->attr.class_pointer;
dimension = CLASS_DATA (c)->attr.dimension;
codimension = CLASS_DATA (c)->attr.codimension;
is_abstract = CLASS_DATA (c)->attr.abstract;
if (sym->ts.type == BT_CLASS && !(sym->result && sym->result != sym))
{
/* F03:C502. */
- if (!gfc_type_is_extensible (CLASS_DATA (sym)->ts.u.derived))
+ if (sym->attr.class_ok
+ && !gfc_type_is_extensible (CLASS_DATA (sym)->ts.u.derived))
{
gfc_error ("Type '%s' of CLASS variable '%s' at %L is not extensible",
CLASS_DATA (sym)->ts.u.derived->name, sym->name,
return FAILURE;
}
- if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.pointer
+ if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.class_pointer
&& CLASS_DATA (c)->ts.u.derived->components == NULL
&& !CLASS_DATA (c)->ts.u.derived->attr.zero_comp)
{
/* C437. */
if (c->ts.type == BT_CLASS
- && !(CLASS_DATA (c)->attr.pointer || CLASS_DATA (c)->attr.allocatable))
+ && !(CLASS_DATA (c)->attr.class_pointer
+ || CLASS_DATA (c)->attr.allocatable))
{
gfc_error ("Component '%s' with CLASS at %L must be allocatable "
"or pointer", c->name, &c->loc);
+2010-07-11 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/44689
+ * gfortran.dg/class_24.f03: New.
+
2010-07-10 Richard Guenther <rguenther@suse.de>
PR lto/44889
--- /dev/null
+! { dg-do compile }
+!
+! PR 44869: [OOP] Missing TARGET check - and wrong code or accepts-invalid?
+!
+! Contributed by Satish.BD <bdsatish@gmail.com>
+
+ type :: test_case
+ end type
+
+ type :: test_suite
+ type(test_case) :: list
+ end type
+
+contains
+
+ subroutine sub(self)
+ class(test_suite), intent(inout) :: self
+ type(test_case), pointer :: tst_case
+ tst_case => self%list ! { dg-error "is neither TARGET nor POINTER" }
+ end subroutine
+
+end