diff options
author | Harald Anlauf <anlauf@gmx.de> | 2021-12-14 21:02:04 +0100 |
---|---|---|
committer | Harald Anlauf <anlauf@gmx.de> | 2021-12-14 21:14:08 +0100 |
commit | e866e1c92ecf88feeeafd5d55348451c9a181f3c (patch) | |
tree | cfe0bb2bbb19260ad15ddf7ceffbbda0aeaf2e62 | |
parent | 7a54d3deecf967029f18aa5ed1fcbdb752e213b9 (diff) | |
download | gcc-e866e1c92ecf88feeeafd5d55348451c9a181f3c.zip gcc-e866e1c92ecf88feeeafd5d55348451c9a181f3c.tar.gz gcc-e866e1c92ecf88feeeafd5d55348451c9a181f3c.tar.bz2 |
Fortran: prevent NULL pointer dereferences checking do-loop contained stuff
gcc/fortran/ChangeLog:
PR fortran/103718
PR fortran/103719
* frontend-passes.c (doloop_contained_procedure_code): Add several
checks to prevent NULL pointer dereferences on valid and invalid
code called within do-loops.
gcc/testsuite/ChangeLog:
PR fortran/103718
PR fortran/103719
* gfortran.dg/do_check_18.f90: New test.
-rw-r--r-- | gcc/fortran/frontend-passes.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/do_check_18.f90 | 27 |
2 files changed, 37 insertions, 7 deletions
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 57b24a1..c106ee0 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -2390,7 +2390,7 @@ doloop_contained_procedure_code (gfc_code **c, switch (co->op) { case EXEC_ASSIGN: - if (co->expr1->symtree->n.sym == do_var) + if (co->expr1->symtree && co->expr1->symtree->n.sym == do_var) gfc_error_now (errmsg, do_var->name, &co->loc, info->procedure->name, &info->where_do); break; @@ -2411,14 +2411,14 @@ doloop_contained_procedure_code (gfc_code **c, break; case EXEC_OPEN: - if (co->ext.open->iostat + if (co->ext.open && co->ext.open->iostat && co->ext.open->iostat->symtree->n.sym == do_var) gfc_error_now (errmsg, do_var->name, &co->ext.open->iostat->where, info->procedure->name, &info->where_do); break; case EXEC_CLOSE: - if (co->ext.close->iostat + if (co->ext.close && co->ext.close->iostat && co->ext.close->iostat->symtree->n.sym == do_var) gfc_error_now (errmsg, do_var->name, &co->ext.close->iostat->where, info->procedure->name, &info->where_do); @@ -2429,7 +2429,8 @@ doloop_contained_procedure_code (gfc_code **c, { case EXEC_INQUIRE: -#define CHECK_INQ(a) do { if (co->ext.inquire->a && \ +#define CHECK_INQ(a) do { if (co->ext.inquire && \ + co->ext.inquire->a && \ co->ext.inquire->a->symtree->n.sym == do_var) \ gfc_error_now (errmsg, do_var->name, \ &co->ext.inquire->a->where, \ @@ -2448,21 +2449,23 @@ doloop_contained_procedure_code (gfc_code **c, #undef CHECK_INQ case EXEC_READ: - if (co->expr1 && co->expr1->symtree->n.sym == do_var) + if (co->expr1 && co->expr1->symtree + && co->expr1->symtree->n.sym == do_var) gfc_error_now (errmsg, do_var->name, &co->expr1->where, info->procedure->name, &info->where_do); /* Fallthrough. */ case EXEC_WRITE: - if (co->ext.dt->iostat + if (co->ext.dt && co->ext.dt->iostat && co->ext.dt->iostat->symtree && co->ext.dt->iostat->symtree->n.sym == do_var) gfc_error_now (errmsg, do_var->name, &co->ext.dt->iostat->where, info->procedure->name, &info->where_do); break; case EXEC_IOLENGTH: - if (co->expr1 && co->expr1->symtree->n.sym == do_var) + if (co->expr1 && co->expr1->symtree + && co->expr1->symtree->n.sym == do_var) gfc_error_now (errmsg, do_var->name, &co->expr1->where, info->procedure->name, &info->where_do); break; diff --git a/gcc/testsuite/gfortran.dg/do_check_18.f90 b/gcc/testsuite/gfortran.dg/do_check_18.f90 new file mode 100644 index 0000000..b06112a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/do_check_18.f90 @@ -0,0 +1,27 @@ +! { dg-do compile } +! PR103718, +! PR103719 - ICE in doloop_contained_procedure_code +! Contributed by G.Steinmetz + +subroutine s1 + integer :: i + do i = 1, 2 + call s + end do +contains + subroutine s + integer :: n + inquire (iolength=n) 0 ! valid + end +end + +subroutine s2 + integer :: i + do i = 1, 2 + call s + end do +contains + subroutine s + shape(1) = 0 ! { dg-error "Non-variable expression" } + end +end |