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 <tkoe...@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;