Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!snorkelwacker!usc!randvax!salzman From: salzman@randvax.UUCP (Isaac Salzman) Newsgroups: gnu.g++.lib.bug Subject: libg++-1.36.3: bug in Itolong (class Integer) Message-ID: <2396@randvax.UUCP> Date: 12 Feb 90 03:26:51 GMT Reply-To: salzman@rand.org (Isaac Salzman) Distribution: gnu Organization: RAND Corp., Santa Monica, Ca. Lines: 94 [built with g++ 1.36.4 on a Sparcstation-1] Itolong in Integer.cc is broken. For small Integers (those that take up only 1 short), there's a chance you'll get back garbage when you assign it to a long. Here are the offending lines of code: /* what if rep->s[1] isn't defined??!! */ unsigned long a = rep->s[SHORT_PER_LONG - 1]; if (a >= I_MINNUM) return (rep->sgn == I_POSITIVE) ? MAXLONG : MINLONG; else { . . . SHORT_PER_LONG ends up as 2, so if you're converting something that takes only 1 short, there's a good chance that you'll get back MAXLONG or MINLONG, depending on what happens to be in rep->s[1]. There are several ways to fix this. However, Lou Moore (mooooore@rand.org) suggested a nice general replacement for Itolong, so here are the context diff's: *** Orig/Integer.cc Mon Feb 5 15:31:29 1990 --- Integer.cc Sun Feb 11 11:15:12 1990 *************** *** 343,374 **** return rep; } - // convert to a legal two's complement long if possible // if too big, return most negative/positive value long Itolong(const IntRep* rep) { ! if (rep->len > SHORT_PER_LONG) return (rep->sgn == I_POSITIVE) ? MAXLONG : MINLONG; else { ! unsigned long a = rep->s[SHORT_PER_LONG - 1]; ! if (a >= I_MINNUM) ! return (rep->sgn == I_POSITIVE) ? MAXLONG : MINLONG; ! else ! { ! a = up(a) | rep->s[SHORT_PER_LONG - 2]; ! if (SHORT_PER_LONG - 3 >= 0) { ! for (int i = SHORT_PER_LONG - 3; i >= 0; --i) ! a = up(a) | rep->s[i]; } ! return (rep->sgn == I_POSITIVE)? a : -((long)a); ! } } } - // test whether op long() will work. // careful about asymmetry between MINLONG & MAXLONG --- 343,367 ---- return rep; } // convert to a legal two's complement long if possible // if too big, return most negative/positive value long Itolong(const IntRep* rep) { ! int i = rep->len-1; ! if (i >= SHORT_PER_LONG) return (rep->sgn == I_POSITIVE) ? MAXLONG : MINLONG; else { ! unsigned long a = rep->s[i]; ! while (i > 0) { ! if ( (a = up(a) | rep->s[--i]) >= I_MINNUM) ! return (rep->sgn == I_POSITIVE) ? MAXLONG : MINLONG; } ! return (rep->sgn == I_POSITIVE)? a : -((long)a); } } // test whether op long() will work. // careful about asymmetry between MINLONG & MAXLONG -- * Isaac J. Salzman ---- * The RAND Corporation - Information Sciences Dept. /o o/ / * 1700 Main St., PO Box 2138, Santa Monica, CA 90406-2138 | v | | * AT&T : +1 213-393-0411 x6421 or x7923 (ISL lab) _| |_/ * Internet : salzman@rand.org / | | * UUCP : !uunet!rand.org!salzman | | |