@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
@cindex array, bounds checking
@cindex bounds checking
@cindex pointer checking
+@cindex memory checking
@cindex range checking
@cindex subscript checking
@cindex checking subscripts
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.
/* 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);
/* 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,
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);
return res;
}
+
/* Allocate memory, using an optional status argument.
This function follows the following pseudo-code: