Dear all, there are several pretty obvious NULL pointer dereferences on valid and invalid code when checking do-loop contained stuff. Reported by Gerhard.
Regtested on x86_64-pc-linux-gnu. OK for mainline/11-branch? Thanks, Harald
From 89bf4b17022890b539cd4b5dbe9bd9142ff8706c Mon Sep 17 00:00:00 2001 From: Harald Anlauf <anl...@gmx.de> Date: Tue, 14 Dec 2021 21:02:04 +0100 Subject: [PATCH] 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. --- gcc/fortran/frontend-passes.c | 17 ++++++++------ gcc/testsuite/gfortran.dg/do_check_18.f90 | 27 +++++++++++++++++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/do_check_18.f90 diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 57b24a11cbe..c106ee0957a 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 00000000000..b06112aa68f --- /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 -- 2.26.2