https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102701

            Bug ID: 102701
           Summary: CLASS (polymorphism) + symbol/expression attribute –
                    wrong attribute status (audit task)
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: burnus at gcc dot gnu.org
  Target Milestone: ---

In patch https://gcc.gnu.org/pipermail/gcc-patches/2021-October/580624.html (*)
I fixed a couple of issues, but I think there are more related to attributes
and CLASS.

(*) committed as r12-4346-geb92cd57a1ebe7cd7589bdbec34d9ae337752ead / PR102541.


In gfc_variable_attr itself:

  optional = attr.optional;
  if (sym->ts.type == BT_CLASS && sym->attr.class_ok && sym->ts.u.derived)
    optional |= CLASS_DATA (sym)->attr.optional;

But at least when queried from trans*.c, the 'var' has been modified to
'var%_data'. Thus, this attribute may not be overwritten in the
'ref->component' loop for '_data'.

I am also not sure whether attr.dummy is properly handled in gfc_variable_attr
or other attributes.

I do see some explicit code in trans*.c, which might or might not need to be
updated:

      if (sym->attr.allocatable)
        {
          if (sym->attr.dummy || sym->attr.result)

For the first point, maybe something like:

diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index d873264a08e..49d56ec5d44 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -2710,3 +2710,2 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
        comp = ref->u.c.component;
-       attr = comp->attr;
        if (ts != NULL && !has_inquiry_part)
@@ -2723,2 +2722,3 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
          {
+           attr = comp->attr;
            codimension = CLASS_DATA (comp)->attr.codimension;
@@ -2726,2 +2726,3 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
            allocatable = CLASS_DATA (comp)->attr.allocatable;
+           optional = false;
          }
@@ -2733,4 +2734,7 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
            else
-             pointer = comp->attr.pointer;
-           allocatable = comp->attr.allocatable;
+             {
+               attr = comp->attr;
+               pointer = comp->attr.pointer;
+               optional = false;
+             }
          }

might be useful – but some careful checking of other attributes should be done.

Reply via email to