aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2023-08-15 17:13:44 +0200
committerMartin Jambor <mjambor@suse.cz>2023-08-15 17:14:21 +0200
commit84e122c34834d9dea189c10fe0bf60c4d1a99fae (patch)
tree54d4bd8e391c69517855244c7be787c2a2025210
parentbed993884b149851fe930b43cf11cbcdf05f1578 (diff)
downloadgcc-84e122c34834d9dea189c10fe0bf60c4d1a99fae.zip
gcc-84e122c34834d9dea189c10fe0bf60c4d1a99fae.tar.gz
gcc-84e122c34834d9dea189c10fe0bf60c4d1a99fae.tar.bz2
Fortran: Avoid accessing gfc_charlen when not looking at BT_CHARACTER (PR 110677)
This patch addresses an issue uncovered by the undefined behavior sanitizer. In function resolve_structure_cons in resolve.cc there is a test starting with: if (cons->expr->ts.type == BT_CHARACTER && comp->ts.u.cl && comp->ts.u.cl->length && comp->ts.u.cl->length->expr_type == EXPR_CONSTANT and UBSAN complained of loads from comp->ts.u.cl->length->expr_type of integer value 1818451807 which is outside of the value range expr_t enum. If I understand the code correctly it the entire load was unwanted because comp->ts.type in those cases is BT_CLASS and not BT_CHARACTER. This patch simply adds a check to make sure it is only accessed in those cases. During review, Harald Anlauf noticed that length types also need to be checked and so I added also checks that he suggested to the condition. Co-authored-by: Harald Anlauf <anlauf@gmx.de> gcc/fortran/ChangeLog: 2023-08-14 Martin Jambor <mjambor@suse.cz> PR fortran/110677 * resolve.cc (resolve_structure_cons): Check comp->ts is character type before accessing stuff through comp->ts.u.cl.
-rw-r--r--gcc/fortran/resolve.cc7
1 files changed, 5 insertions, 2 deletions
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index e7c8d91..f51674f 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -1396,11 +1396,14 @@ resolve_structure_cons (gfc_expr *expr, int init)
the one of the structure, ensure this if the lengths are known at
compile time and when we are dealing with PARAMETER or structure
constructors. */
- if (cons->expr->ts.type == BT_CHARACTER && comp->ts.u.cl
- && comp->ts.u.cl->length
+ if (cons->expr->ts.type == BT_CHARACTER
+ && comp->ts.type == BT_CHARACTER
+ && comp->ts.u.cl && comp->ts.u.cl->length
&& comp->ts.u.cl->length->expr_type == EXPR_CONSTANT
&& cons->expr->ts.u.cl && cons->expr->ts.u.cl->length
&& cons->expr->ts.u.cl->length->expr_type == EXPR_CONSTANT
+ && cons->expr->ts.u.cl->length->ts.type == BT_INTEGER
+ && comp->ts.u.cl->length->ts.type == BT_INTEGER
&& mpz_cmp (cons->expr->ts.u.cl->length->value.integer,
comp->ts.u.cl->length->value.integer) != 0)
{