]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/42958 (Weird temporary array allocation)
authorTobias Burnus <burnus@net-b.de>
Sat, 20 Feb 2010 08:31:25 +0000 (09:31 +0100)
committerTobias Burnus <burnus@gcc.gnu.org>
Sat, 20 Feb 2010 08:31:25 +0000 (09:31 +0100)
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

gcc/fortran/ChangeLog
gcc/fortran/invoke.texi
gcc/fortran/libgfortran.h
gcc/fortran/options.c
gcc/fortran/trans.c

index db05fd3e3ca510bd44ef86b3abde40454830534e..8776bd54d2002b310f3244ba370259b2f09c9e2e 100644 (file)
@@ -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
index 88a395d04d007923a65c5befc090cb8340cd604e..9fe75d17b8b716537de83c86e6006d245ffe5f0e 100644 (file)
@@ -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.
 
index d66020717a47500a9b268a1f2b28e2bcef8c6590..c39f54b19fc97f9fd6287da906b41cca5ba4077b 100644 (file)
@@ -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.  */
index 9296a0be66769d4c5b6040e137cefb015dd9dbe3..a9ce56015ae15cde2c6b77fe6d88b68bc99ecddf 100644 (file)
@@ -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)
index 535e639faad44ae7d266d652b5851e2a4b431590..6958f0272b51c0794f2b1323e658bdd5129a7d16 100644 (file)
@@ -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: