Commit 65713e5b by Tobias Burnus Committed by Tobias Burnus

re PR fortran/27588 (-fbounds-check should catch substring out of range accesses)

fortran/
2006-11-15  Tobias Burnus  <burnus@net-b.de>
            Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>

       PR fortran/27588
       * trans-expr.c (gfc_conv_substring): Add bounds checking.
         (gfc_conv_variable, gfc_conv_substring_expr): Pass more
         arguments to gfc_conv_substring.

testsuite/
2006-11-15  Tobias Burnus  <burnus@net-b.de>

       PR fortran/27588
       * gfortran.dg/char_bounds_check_fail_1.f90: New test.


Co-Authored-By: Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>

From-SVN: r118852
parent 8c894ae2
2006-11-15 Tobias Burnus <burnus@net-b.de> 2006-11-15 Tobias Burnus <burnus@net-b.de>
Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/27588
* trans-expr.c (gfc_conv_substring): Add bounds checking.
(gfc_conv_variable, gfc_conv_substring_expr): Pass more
arguments to gfc_conv_substring.
2006-11-15 Tobias Burnus <burnus@net-b.de>
PR fortran/29806 PR fortran/29806
* parse.c (parse_contained): Check for empty contains statement. * parse.c (parse_contained): Check for empty contains statement.
......
...@@ -234,13 +234,16 @@ gfc_trans_init_string_length (gfc_charlen * cl, stmtblock_t * pblock) ...@@ -234,13 +234,16 @@ gfc_trans_init_string_length (gfc_charlen * cl, stmtblock_t * pblock)
static void static void
gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind) gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
const char *name, locus *where)
{ {
tree tmp; tree tmp;
tree type; tree type;
tree var; tree var;
tree fault;
gfc_se start; gfc_se start;
gfc_se end; gfc_se end;
char *msg;
type = gfc_get_character_type (kind, ref->u.ss.length); type = gfc_get_character_type (kind, ref->u.ss.length);
type = build_pointer_type (type); type = build_pointer_type (type);
...@@ -272,6 +275,33 @@ gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind) ...@@ -272,6 +275,33 @@ gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind)
gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node); gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
gfc_add_block_to_block (&se->pre, &end.pre); gfc_add_block_to_block (&se->pre, &end.pre);
} }
if (flag_bounds_check)
{
/* Check lower bound. */
fault = fold_build2 (LT_EXPR, boolean_type_node, start.expr,
build_int_cst (gfc_charlen_type_node, 1));
if (name)
asprintf (&msg, "Substring out of bounds: lower bound of '%s' "
"is less than one", name);
else
asprintf (&msg, "Substring out of bounds: lower bound "
"is less than one");
gfc_trans_runtime_check (fault, msg, &se->pre, where);
gfc_free (msg);
/* Check upper bound. */
fault = fold_build2 (GT_EXPR, boolean_type_node, end.expr,
se->string_length);
if (name)
asprintf (&msg, "Substring out of bounds: upper bound of '%s' "
"exceeds string length", name);
else
asprintf (&msg, "Substring out of bounds: upper bound "
"exceeds string length");
gfc_trans_runtime_check (fault, msg, &se->pre, where);
gfc_free (msg);
}
tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node,
build_int_cst (gfc_charlen_type_node, 1), build_int_cst (gfc_charlen_type_node, 1),
start.expr); start.expr);
...@@ -485,7 +515,8 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr) ...@@ -485,7 +515,8 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
break; break;
case REF_SUBSTRING: case REF_SUBSTRING:
gfc_conv_substring (se, ref, expr->ts.kind); gfc_conv_substring (se, ref, expr->ts.kind,
expr->symtree->name, &expr->where);
break; break;
default: default:
...@@ -2958,7 +2989,7 @@ gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr) ...@@ -2958,7 +2989,7 @@ gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr))); se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1; TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
gfc_conv_substring(se,ref,expr->ts.kind); gfc_conv_substring(se,ref,expr->ts.kind,NULL,&expr->where);
} }
......
2006-11-15 Tobias Burnus <burnus@net-b.de> 2006-11-15 Tobias Burnus <burnus@net-b.de>
PR fortran/27588
* gfortran.dg/char_bounds_check_fail_1.f90: New test.
2006-11-15 Tobias Burnus <burnus@net-b.de>
PR fortran/29806 PR fortran/29806
* gfortran.dg/contains.f90: New test. * gfortran.dg/contains.f90: New test.
* gfortran.dg/derived_function_interface_1.f90: Add a dg-warning. * gfortran.dg/derived_function_interface_1.f90: Add a dg-warning.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment