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

--- Comment #2 from kargls at comcast dot net ---
(In reply to kargls from comment #1)
> (In reply to Keith Refson from comment #0)
> 
> > 
> > I suggest at least issuing a warning to expect undefined run-time behaviour!
> >
> 
> Here's a patch hidden behind -Wsurprising.
> 

And now the patch. :-)

diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 9c66c25e059..9aef66b4616 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -6856,6 +6856,32 @@ gfc_check_transfer (gfc_expr *source, gfc_expr *mold,
gfc_expr *size)
   if (!warn_surprising)
     return true;

+  /* TRANSFER does not do a deep copy.  So, if SOURCE contains an allocatable
+     or pointer component, then this can lead to undefined behavior.  */
+
+  if (source->expr_type == EXPR_VARIABLE && source->ts.type == BT_DERIVED)
+    {
+      bool saw = false;
+      gfc_component *c;
+
+      for (c = source->ts.u.derived->components; c; c = c->next)
+       {
+         if (c->attr.allocatable || c->attr.pointer)
+           {
+             saw = true;
+             break;
+           }
+       }
+
+      if (saw)
+       gfc_warning (OPT_Wsurprising,
+                    "SOURCE at %L contains an ALLOCATABLE or POINTER "
+                    "component, which may lead to undefined behavior because "
+                    "TRANSFER does not do a deep copy",
+                    &source->where);
+    }    
+
+
   /* If we can't calculate the sizes, we cannot check any more.
      Return true for that case.  */

Reply via email to