This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, Fortran] PR 52196 add -Wrealloc-lhs(-all)

Hi all,

in order to gain an overview for our code whether the recent RESHAPE (and friends) bug affects us and to determine for which assignment a reallocation happens, useful to mitigate performance issues, I added -Wrealloc-lhs and -Wrealloc-lhs-all.

The flag -Wrealloc-lhs is the more useful flag: It's about arrays of intrinsic types, which are more likely to appear in hot loops than other types of reallocatable variables such as derived types or (scalar) character variables with deferred length.

Using it, I also found that there is a rather common class of expressions, related to scaling, array addition or complex conjugation, where the same array is on the LHS and RHS. In that case, gfortran should avoid inserting the reallocation. (Cf. PR 52243.) Fortunately, -O0 is often sufficient to remove the reallocation code. In turn, the warning might be printed even if at the end no realloc code is generated or present with -O1. Nevertheless, it can help to aid optimizing the code, though, blindly adding "(:,:)" everywhere doesn't make sense - but it also doesn't harm either. (At least for code which doesn't use realloc on assignment on purpose ;-)

Build and regtested on x86-64-linux.
OK for the (4.8?) trunk?

2012-02-14  Tobias Burnus  <>

	PR fortran/52196
	* lang.opt (Wrealloc-lhs, Wrealloc-lhs-all): New flags.
	* gfortran.h (gfc_option_t): Add them.
	* options.c (gfc_init_options, gfc_post_options,
	gfc_handle_option): Handle them.
	* resolve.c (resolve_ordinary_assign): Ditto.
	* invoke.texi: Document them.

2012-02-14  Tobias Burnus  <>

	PR fortran/52196
	* gfortran.dg/realloc_on_assign_13.f90: New.

Index: gcc/fortran/options.c
--- gcc/fortran/options.c	(revision 184200)
+++ gcc/fortran/options.c	(working copy)
@@ -110,6 +110,8 @@ gfc_init_options (unsigned int decoded_options_cou
   gfc_option.warn_align_commons = 1;
   gfc_option.warn_real_q_constant = 0;
   gfc_option.warn_unused_dummy_argument = 0;
+  gfc_option.warn_realloc_lhs = 0;
+  gfc_option.warn_realloc_lhs_all = 0;
   gfc_option.max_errors = 25;
   gfc_option.flag_all_intrinsics = 0;
@@ -436,6 +438,9 @@ gfc_post_options (const char **pfilename)
   if (gfc_option.flag_frontend_optimize == -1)
     gfc_option.flag_frontend_optimize = optimize;
+  if (gfc_option.warn_realloc_lhs_all)
+    gfc_option.warn_realloc_lhs = 1;
   gfc_cpp_post_options ();
 /* FIXME: return gfc_cpp_preprocess_only ();
@@ -648,6 +653,14 @@ gfc_handle_option (size_t scode, const char *arg,
       gfc_option.warn_line_truncation = value;
+    case OPT_Wrealloc_lhs:
+      gfc_option.warn_realloc_lhs = value;
+      break;
+    case OPT_Wrealloc_lhs_all:
+      gfc_option.warn_realloc_lhs_all = value;
+      break;
     case OPT_Wreturn_type:
       warn_return_type = value;
Index: gcc/fortran/gfortran.h
--- gcc/fortran/gfortran.h	(revision 184200)
+++ gcc/fortran/gfortran.h	(working copy)
@@ -2215,6 +2215,8 @@ typedef struct
   int warn_align_commons;
   int warn_real_q_constant;
   int warn_unused_dummy_argument;
+  int warn_realloc_lhs;
+  int warn_realloc_lhs_all;
   int max_errors;
   int flag_all_intrinsics;
Index: gcc/fortran/lang.opt
--- gcc/fortran/lang.opt	(revision 184200)
+++ gcc/fortran/lang.opt	(working copy)
@@ -246,6 +246,14 @@ Wreal-q-constant
 Fortran Warning
 Warn about real-literal-constants with 'q' exponent-letter
+Fortran Warning
+Warn when a left-hand-side array variable is reallocated
+Fortran Warning
+Warn when a left-hand-side variable is reallocated
 Fortran Warning
 ; Documented in C
Index: gcc/fortran/invoke.texi
--- gcc/fortran/invoke.texi	(revision 184200)
+++ gcc/fortran/invoke.texi	(working copy)
@@ -146,9 +146,8 @@ and warnings}.
 -Wconversion -Wfunction-elimination -Wimplicit-interface @gol
 -Wimplicit-procedure -Wintrinsic-shadow -Wintrinsics-std @gol
 -Wline-truncation -Wno-align-commons -Wno-tabs -Wreal-q-constant @gol
--Wsurprising -Wunderflow -Wunused-parameter -fmax-errors=@var{n}
--fsyntax-only @gol
--pedantic -pedantic-errors
+-Wsurprising -Wunderflow -Wunused-parameter -Wrealloc-lhs Wrealloc-lhs-all @gol
+-fmax-errors=@var{n} -fsyntax-only -pedantic -pedantic-errors
 @item Debugging Options
@@ -911,7 +910,24 @@ off via @option{-Wno-align-commons}. See also @opt
 Warn if any calls to functions are eliminated by the optimizations
 enabled by the @option{-ffrontend-optimize} option.
+@item -Wrealloc-lhs
+@opindex @code{Wrealloc-lhs}
+@cindex Reallocate the LHS in assignments, notification
+Warn when the compiler might insert code to for allocation or reallocation of
+an allocatable array variable of intrinsic type in intrinsic assignments.  In
+hot loops, the Fortran 2003 reallocation feature may reduce the performance.
+If the array is already allocated with the correct shape, consider using a
+whole-array array-spec (e.g. @code{(:,:,:)}) for the variable on the left-hand
+side to prevent the reallocation check. Note that in some cases the warning
+is shown, even if the compiler will optimize reallocation checks away.  For
+instance, when the right-hand side contains the same variable multiplied by
+a scalar.  See also @option{-frealloc-lhs}.
+@item -Wrealloc-lhs-all
+@opindex @code{Wrealloc-lhs-all}
+Warn when the compiler inserts code to for allocation or reallocation of an
+allocatable variable; this includes scalars and derived types.
 @item -Werror
 @opindex @code{Werror}
 @cindex warnings, to errors
@@ -1553,7 +1569,8 @@ need to be in effect. The parentheses protection i
 @cindex Reallocate the LHS in assignments
 An allocatable left-hand side of an intrinsic assignment is automatically
 (re)allocated if it is either unallocated or has a different shape. The
-option is enabled by default except when @option{-std=f95} is given.
+option is enabled by default except when @option{-std=f95} is given. See
+also @option{-Wrealloc-lhs}.
 @item -faggressive-function-elimination
 @opindex @code{faggressive-function-elimination}
Index: gcc/fortran/resolve.c
--- gcc/fortran/resolve.c	(revision 184200)
+++ gcc/fortran/resolve.c	(working copy)
@@ -9237,6 +9237,20 @@ resolve_ordinary_assign (gfc_code *code, gfc_names
   gfc_check_assign (lhs, rhs, 1);
+  if (gfc_option.flag_realloc_lhs && gfc_expr_attr (lhs).allocatable)
+    {
+      if (lhs->rank && lhs->ts.type != BT_CLASS && lhs->ts.type != BT_DERIVED
+	  && rhs->rank && gfc_option.warn_realloc_lhs)
+	gfc_warning ("Code for reallocating the allocatable array at %L might "
+		     "be added", &lhs->where);
+      else if (gfc_option.warn_realloc_lhs_all && (lhs->rank == 0 || rhs->rank))
+	gfc_warning ("Code for reallocating the allocatable variable at %L "
+		     "might be added", &lhs->where);
+    }
   return false;
Index: gcc/testsuite/gfortran.dg/realloc_on_assign_13.f90
--- gcc/testsuite/gfortran.dg/realloc_on_assign_13.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/realloc_on_assign_13.f90	(working copy)
@@ -0,0 +1,16 @@
+! { dg-do compile }
+! { dg-options "-Wrealloc-lhs-all -Wrealloc-lhs" }
+! PR fortran/52196
+type t
+  integer :: x
+end type t
+integer, allocatable :: a(:), b
+type(t), allocatable :: c(:)
+allocate(a(2), b, c(1))
+b = 4      ! { dg-warning "Code for reallocating the allocatable variable" }
+a = [b,b]  ! { dg-warning "Code for reallocating the allocatable array" }
+c = [t(4)] ! { dg-warning "Code for reallocating the allocatable variable" }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]