summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2014-01-28 21:47:32 +0200
committerArnold D. Robbins <arnold@skeeve.com>2014-01-28 21:47:32 +0200
commitd6c537443dc5954ca21a849b45dc5adedca6211c (patch)
treeb92c6f8651e12dcc268242e1d93ebf3bf583f075
parent6520f31b24575ce7308a8b42c8b617568db6c4d8 (diff)
downloadgawk-d6c537443dc5954ca21a849b45dc5adedca6211c.tar.gz
Fix bug that only showed up on 32 bit systems with MPFR.
-rw-r--r--ChangeLog7
-rw-r--r--awkgram.c13
-rw-r--r--awkgram.y13
3 files changed, 25 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index aac38973..3849492b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-01-28 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (negate_num): If just a double, return. Fixes a bug
+ that showed up on 32-bit systems with MPFR. Thanks to Eli Zaretskii
+ and Corinna Vinschen for the report. Also, free the MPZ integer.
+ Thanks to valgrind for the report.
+
2014-01-24 Arnold D. Robbins <arnold@skeeve.com>
* configure.ac, field.c: Update copyright year.
diff --git a/awkgram.c b/awkgram.c
index 657a1627..58ac3480 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -4514,10 +4514,13 @@ negate_num(NODE *n)
{
int tval = 0;
- if (! is_mpg_number(n))
+ if (! is_mpg_number(n)) {
n->numbr = -n->numbr;
+ return;
+ }
+
#ifdef HAVE_MPFR
- else if (is_mpg_integer(n)) {
+ if (is_mpg_integer(n)) {
if (! iszero(n)) {
mpz_neg(n->mpg_i, n->mpg_i);
return;
@@ -4526,9 +4529,11 @@ negate_num(NODE *n)
/*
* 0 --> -0 conversion. Requires turning the MPG integer
* into an MPFR float.
- *
- * So, convert and fall through.
*/
+
+ mpz_clear(n->mpg_i); /* release the integer storage */
+
+ /* Convert and fall through. */
tval = mpfr_set_d(n->mpg_numbr, 0.0, ROUND_MODE);
IEEE_FMT(n->mpg_numbr, tval);
n->flags &= ~MPZN;
diff --git a/awkgram.y b/awkgram.y
index fd83d6db..6bbc150a 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -1966,10 +1966,13 @@ negate_num(NODE *n)
{
int tval = 0;
- if (! is_mpg_number(n))
+ if (! is_mpg_number(n)) {
n->numbr = -n->numbr;
+ return;
+ }
+
#ifdef HAVE_MPFR
- else if (is_mpg_integer(n)) {
+ if (is_mpg_integer(n)) {
if (! iszero(n)) {
mpz_neg(n->mpg_i, n->mpg_i);
return;
@@ -1978,9 +1981,11 @@ negate_num(NODE *n)
/*
* 0 --> -0 conversion. Requires turning the MPG integer
* into an MPFR float.
- *
- * So, convert and fall through.
*/
+
+ mpz_clear(n->mpg_i); /* release the integer storage */
+
+ /* Convert and fall through. */
tval = mpfr_set_d(n->mpg_numbr, 0.0, ROUND_MODE);
IEEE_FMT(n->mpg_numbr, tval);
n->flags &= ~MPZN;