This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch, libfortran] Fix PR 54736, memory corruption with GFORTRAN_CONVERT_UNIT
- From: Thomas Koenig <tkoenig at netcologne dot de>
- To: "fortran at gcc dot gnu dot org" <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 29 Sep 2012 20:01:20 +0200
- Subject: [patch, libfortran] Fix PR 54736, memory corruption with GFORTRAN_CONVERT_UNIT
Hello world,
the attached patch fixes the PR. The logic for processing
GFORTRAN_CONVERT_UNIT had been quite wrong. I have checked
that the original test case, plus a few more, no longer cause
assertion failures or memory corruption (also checked with
valgrind). No test case because it is not possible to set
environment variables from the testsuite.
Regression-tested. OK for trunk?
I would also like to backport this to 4.7, and maybe 4.6. What
do you think?
Thomas
2012-09-29 Thomas König <tkoenig@gcc.gnu.org>
PR libfortran/54736
* runtime/environ.c (search_unit): Correct logic
for binary search.
(mark_single): Fix index errors.
Index: runtime/environ.c
===================================================================
--- runtime/environ.c (Revision 191649)
+++ runtime/environ.c (Arbeitskopie)
@@ -459,21 +459,34 @@ search_unit (int unit, int *ip)
{
int low, high, mid;
- low = -1;
- high = n_elist;
+ if (n_elist == 0)
+ {
+ *ip = 0;
+ return 0;
+ }
+
+ low = 0;
+ high = n_elist - 1;
while (high - low > 1)
{
mid = (low + high) / 2;
- if (unit <= elist[mid].unit)
+ if (unit == elist[mid].unit)
+ {
+ *ip = mid;
+ return 1;
+ }
+ else if (unit > elist[mid].unit)
+ low = mid;
+ else
high = mid;
- else
- low = mid;
}
- *ip = high;
- if (elist[high].unit == unit)
- return 1;
+
+ if (unit > elist[high].unit)
+ *ip = high;
else
- return 0;
+ *ip = low;
+
+ return 0;
}
/* This matches a keyword. If it is found, return the token supplied,
@@ -588,13 +601,13 @@ mark_single (int unit)
}
if (search_unit (unit, &i))
{
- elist[unit].conv = endian;
+ elist[i].conv = endian;
}
else
{
- for (j=n_elist; j>=i; j--)
+ for (j=n_elist-1; j>=i; j--)
elist[j+1] = elist[j];
-
+
n_elist += 1;
elist[i].unit = unit;
elist[i].conv = endian;