aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Burnus <burnus@net-b.de>2010-02-20 09:31:25 +0100
committerTobias Burnus <burnus@gcc.gnu.org>2010-02-20 09:31:25 +0100
commit22bdbb0fd240000f224a62ccf1e5460140a482ce (patch)
tree394c4ce0617433ffcc3399c7facb3e046d446672
parentf233f7ed7fe361eeab0fdc35ff821b87b8d10a59 (diff)
downloadgcc-22bdbb0fd240000f224a62ccf1e5460140a482ce.zip
gcc-22bdbb0fd240000f224a62ccf1e5460140a482ce.tar.gz
gcc-22bdbb0fd240000f224a62ccf1e5460140a482ce.tar.bz2
re PR fortran/42958 (Weird temporary array allocation)
2010-02-20 Tobias Burnus <burnus@net-b.de> PR fortran/42958 * libgfortran.h: Add GFC_RTCHECK_MEM. * invoke.texi (-fcheck=): Document -fcheck=mem. * tranc.c (gfc_call_malloc): Remove negative-size run-time error and enable malloc-success check only with -fcheck=mem. * option.c (gfc_handle_runtime_check_option): Add -fcheck=mem. From-SVN: r156923
-rw-r--r--gcc/fortran/ChangeLog9
-rw-r--r--gcc/fortran/invoke.texi8
-rw-r--r--gcc/fortran/libgfortran.h3
-rw-r--r--gcc/fortran/options.c5
-rw-r--r--gcc/fortran/trans.c43
5 files changed, 40 insertions, 28 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index db05fd3..8776bd5 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,12 @@
+2010-02-20 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/42958
+ * libgfortran.h: Add GFC_RTCHECK_MEM.
+ * invoke.texi (-fcheck=): Document -fcheck=mem.
+ * tranc.c (gfc_call_malloc): Remove negative-size run-time error
+ and enable malloc-success check only with -fcheck=mem.
+ * option.c (gfc_handle_runtime_check_option): Add -fcheck=mem.
+
2010-02-16 Tobias Burnus <burnus@net-b.de>
PR fortran/43040
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 88a395d..9fe75d1 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -166,7 +166,7 @@ and warnings}.
@gccoptlist{-fno-automatic -ff2c -fno-underscoring @gol
-fwhole-file -fsecond-underscore @gol
-fbounds-check -fcheck-array-temporaries -fmax-array-constructor =@var{n} @gol
--fcheck=@var{<all|array-temps|bounds|do|pointer|recursion>}
+-fcheck=@var{<all|array-temps|bounds|do|mem|pointer|recursion>}
-fmax-stack-var-size=@var{n} @gol
-fpack-derived -frepack-arrays -fshort-enums -fexternal-blas @gol
-fblas-matmul-limit=@var{n} -frecursive -finit-local-zero @gol
@@ -1216,6 +1216,7 @@ by use of the @option{-ff2c} option.
@cindex array, bounds checking
@cindex bounds checking
@cindex pointer checking
+@cindex memory checking
@cindex range checking
@cindex subscript checking
@cindex checking subscripts
@@ -1254,6 +1255,11 @@ checking substring references.
Enable generation of run-time checks for invalid modification of loop
iteration variables.
+@item @samp{mem}
+Enable generation of run-time checks for memory allocation.
+Note: This option does not affect explicit allocations using the
+@code{ALLOCATE} statement, which will be always checked.
+
@item @samp{pointer}
Enable generation of run-time checks for pointers and allocatables.
diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h
index d660207..c39f54b 100644
--- a/gcc/fortran/libgfortran.h
+++ b/gcc/fortran/libgfortran.h
@@ -48,9 +48,10 @@ along with GCC; see the file COPYING3. If not see
#define GFC_RTCHECK_RECURSION (1<<2)
#define GFC_RTCHECK_DO (1<<3)
#define GFC_RTCHECK_POINTER (1<<4)
+#define GFC_RTCHECK_MEM (1<<5)
#define GFC_RTCHECK_ALL (GFC_RTCHECK_BOUNDS | GFC_RTCHECK_ARRAY_TEMPS \
| GFC_RTCHECK_RECURSION | GFC_RTCHECK_DO \
- | GFC_RTCHECK_POINTER)
+ | GFC_RTCHECK_POINTER | GFC_RTCHECK_MEM)
/* Possible values for the CONVERT I/O specifier. */
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 9296a0b..a9ce560 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -482,11 +482,12 @@ gfc_handle_runtime_check_option (const char *arg)
{
int result, pos = 0, n;
static const char * const optname[] = { "all", "bounds", "array-temps",
- "recursion", "do", "pointer", NULL };
+ "recursion", "do", "pointer",
+ "mem", NULL };
static const int optmask[] = { GFC_RTCHECK_ALL, GFC_RTCHECK_BOUNDS,
GFC_RTCHECK_ARRAY_TEMPS,
GFC_RTCHECK_RECURSION, GFC_RTCHECK_DO,
- GFC_RTCHECK_POINTER,
+ GFC_RTCHECK_POINTER, GFC_RTCHECK_MEM,
0 };
while (*arg)
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 535e639..6958f02 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -497,13 +497,12 @@ gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
/* Call malloc to allocate size bytes of memory, with special conditions:
- + if size < 0, generate a runtime error,
- + if size == 0, return a malloced area of size 1,
+ + if size <= 0, return a malloced area of size 1,
+ if malloc returns NULL, issue a runtime error. */
tree
gfc_call_malloc (stmtblock_t * block, tree type, tree size)
{
- tree tmp, msg, negative, malloc_result, null_result, res;
+ tree tmp, msg, malloc_result, null_result, res;
stmtblock_t block2;
size = gfc_evaluate_now (size, block);
@@ -514,18 +513,7 @@ gfc_call_malloc (stmtblock_t * block, tree type, tree size)
/* Create a variable to hold the result. */
res = gfc_create_var (prvoid_type_node, NULL);
- /* size < 0 ? */
- negative = fold_build2 (LT_EXPR, boolean_type_node, size,
- build_int_cst (size_type_node, 0));
- msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const
- ("Attempt to allocate a negative amount of memory."));
- tmp = fold_build3 (COND_EXPR, void_type_node, negative,
- build_call_expr_loc (input_location,
- gfor_fndecl_runtime_error, 1, msg),
- build_empty_stmt (input_location));
- gfc_add_expr_to_block (block, tmp);
-
- /* Call malloc and check the result. */
+ /* Call malloc. */
gfc_start_block (&block2);
size = fold_build2 (MAX_EXPR, size_type_node, size,
@@ -535,15 +523,21 @@ gfc_call_malloc (stmtblock_t * block, tree type, tree size)
fold_convert (prvoid_type_node,
build_call_expr_loc (input_location,
built_in_decls[BUILT_IN_MALLOC], 1, size)));
- null_result = fold_build2 (EQ_EXPR, boolean_type_node, res,
- build_int_cst (pvoid_type_node, 0));
- msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const
- ("Memory allocation failed"));
- tmp = fold_build3 (COND_EXPR, void_type_node, null_result,
- build_call_expr_loc (input_location,
- gfor_fndecl_os_error, 1, msg),
- build_empty_stmt (input_location));
- gfc_add_expr_to_block (&block2, tmp);
+
+ /* Optionally check whether malloc was successful. */
+ if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
+ {
+ null_result = fold_build2 (EQ_EXPR, boolean_type_node, res,
+ build_int_cst (pvoid_type_node, 0));
+ msg = gfc_build_addr_expr (pchar_type_node,
+ gfc_build_localized_cstring_const ("Memory allocation failed"));
+ tmp = fold_build3 (COND_EXPR, void_type_node, null_result,
+ build_call_expr_loc (input_location,
+ gfor_fndecl_os_error, 1, msg),
+ build_empty_stmt (input_location));
+ gfc_add_expr_to_block (&block2, tmp);
+ }
+
malloc_result = gfc_finish_block (&block2);
gfc_add_expr_to_block (block, malloc_result);
@@ -553,6 +547,7 @@ gfc_call_malloc (stmtblock_t * block, tree type, tree size)
return res;
}
+
/* Allocate memory, using an optional status argument.
This function follows the following pseudo-code: