2012-02-14 Tobias Burnus <burnus@net-b.de>
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 <burnus@net-b.de>
PR fortran/52196
* gfortran.dg/realloc_on_assign_13.f90: New.
===================================================================
@@ -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;
break;
+ 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;
break;
===================================================================
@@ -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;
===================================================================
@@ -246,6 +246,14 @@ Wreal-q-constant
Fortran Warning
Warn about real-literal-constants with 'q' exponent-letter
+Wrealloc-lhs
+Fortran Warning
+Warn when a left-hand-side array variable is reallocated
+
+Wrealloc-lhs-all
+Fortran Warning
+Warn when a left-hand-side variable is reallocated
+
Wreturn-type
Fortran Warning
; Documented in C
===================================================================
@@ -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}
===================================================================
@@ -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;
}
===================================================================
@@ -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" }
+end