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

--- Comment #12 from Fritz Reese <foreese at gcc dot gnu.org> ---
(In reply to Thomas Koenig from comment #11)
> (In reply to janus from comment #10)
...
> 
> If possible, I would prefer to set the locus where it is generated,
> not conditionally later.
> 
> Unfortunately, I cannot currently look into this due to PR 86450 :-(
> 
> If I had a bootstrapping gcc, I would probably look at
> 
>       /* Fetch or generate an initializer for the component.  */
>       tmp = component_initializer (comp, generate);
> 
> and see if the locus is set correctly at that point, then
> (possibly) go back to component_initializer to see where this is
> missing.

I agree. I traced the issue and it appears locus info is not set for
gfc_components which are created from a module definition, so c->loc is empty.
Given that, this line is erroneous:

> static gfc_expr *
> component_initializer (gfc_component *c, bool generate)
> [...]
>      init = gfc_get_null_expr (&c->loc);

Before r262442 the locus for the NULL expression was originally copied from the
derived type to which the component belonged. (This is less than ideal when the
message actually refers to the component, which is why this behavior was
"fixed" in r262442.)

If we set the component's locus when it is loaded from a module, the following
patch fixes the issue and retains sane location information for the component
and its initializer:

diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index b120501beb7..27d68f6b1b5 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -2848,6 +2848,8 @@ mio_component (gfc_component *c, int vtype)
   if (c->attr.proc_pointer)
     mio_typebound_proc (&c->tb);

+  c->loc = gfc_current_locus;
+
   mio_rparen ();
 }

However if we prefer not to set the component's locus for whatever reason, the
following alternative patch also fixes the issue, where the component's
initializer has its locus set to that of the derived type declaration:

diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 6a7e09589a7..c63b41c36e4 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -4444,7 +4444,7 @@ comp_pointer (gfc_component *comp)
    Only generate an initializer if generate is true.  */

 static gfc_expr *
-component_initializer (gfc_component *c, bool generate)
+component_initializer (gfc_typespec *derived, gfc_component *c, bool generate)
 {
   gfc_expr *init = NULL;

@@ -4453,7 +4453,10 @@ component_initializer (gfc_component *c, bool generate)
      do not already have an initializer.  */
   if (comp_allocatable (c) || (generate && comp_pointer (c) &&
!c->initializer))
     {
-      init = gfc_get_null_expr (&c->loc);
+      if (c->loc.nextc && c->loc.lb)
+       init = gfc_get_null_expr (&c->loc);
+      else
+       init = gfc_get_null_expr (&derived->declared_at);
       init->ts = c->ts;
       return init;
     }
@@ -4588,7 +4591,7 @@ gfc_generate_initializer (gfc_typespec *ts, bool
generate)
       gfc_constructor *ctor = gfc_constructor_get();

       /* Fetch or generate an initializer for the component.  */
-      tmp = component_initializer (comp, generate);
+      tmp = component_initializer (ts->u.derived, comp, generate);
       if (tmp)
        {
          /* Save the component ref for STRUCTUREs and UNIONs.  */


I am currently running regression tests to verify these patches. If both pass
and I have not missed something obvious I would prefer adding location info to
the component when loading from a module (the first patch).

Reply via email to