Subject: Re: bug#12350: Composites identified as primes in factor.c (when HAVE_GMP)

From: Pádraig Brady <[email-masked]>
Date: Mon, 08 Oct 2012 15:47:44 +0100

On 10/08/2012 11:52 AM, Jim Meyering wrote:
> Pádraig Brady wrote:
>> On 10/07/2012 10:00 AM, Jim Meyering wrote:
>>> Torbjorn Granlund wrote:
>>>> Jim Meyering <[email-masked]> writes:
>>>>
>>>>     How about this in place of the final sentence?
>>>>
>>>>                                                         The new program also
>>>>         runs a deterministic primality test for each prime factor, not just
>>>>         a probabilistic test.
>>>>
>>>> That's better, thanks.
>>>
>>> I pushed the actual bug fix (for the issue mentioned in the Subject)
>>> long ago, so I'm closing this "issue".
>>>
>>> Regarding your upcoming improvements, please start a new thread
>>> when you're ready to discuss them, so that your comments are not
>>> lost in the volume of with this now-"done" bug report.
>>
>> A small amendment I'm going to push is not to rely on GMP5.
>> GMP4 on my fedora 15 system doesn't have mpz_inits().
>> i.e. support for initializing multiple variables at once.
>>
>> Patch is simple enough...
>
> Hi Pádraig,
>
> Thanks, but wouldn't that be a slight "pessimization"?
> What do you think about providing the missing function instead?
> Maybe not worth the hassle, but still, it would avoid adding those 12
> in-function lines.  factor.c is already large and complex enough that
> every little bit helps.

Borderline, but to align code with newer libs,
I've done as you suggest in the attached.

> BTW, Fedora 15 passed "end of life" back in June.

Right, so it's not too old.
The same issue will affect debian stable, RHEL, ...

cheers,
Pádraig.
>From 8052c5bf1c5c6dc92b420ce2ed3c6595d9b31797 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email-masked]>
Date: Mon, 8 Oct 2012 11:38:41 +0100
Subject: [PATCH] build: support older GMP versions

The new factor code introduced usage of mpz_inits() and
mpz_clears(), which are only available since GMP >= 5,
and will result in a compile error when missing.

* m4/gmp.m4 (cu_GMP): Define HAVE_DECL_MPZ_INITS appropriately.
* src/factor (mpz_inits): New function, defined where missing.
(mpz_clears): Likewise.
---
 m4/gmp.m4    |    2 ++
 src/factor.c |   23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/m4/gmp.m4 b/m4/gmp.m4
index e337e16..59a664f 100644
--- a/m4/gmp.m4
+++ b/m4/gmp.m4
@@ -30,6 +30,8 @@ AC_DEFUN([cu_GMP],
         LIB_GMP=$ac_cv_search___gmpz_init
         AC_DEFINE([HAVE_GMP], [1],
           [Define if you have GNU libgmp (or replacement)])
+        # This only available in GMP >= 5
+        AC_CHECK_DECLS([mpz_inits], [], [], [[#include <gmp.h>]])
        }],
       [AC_MSG_WARN([libgmp development library was not found or not usable.])
        AC_MSG_WARN([AC_PACKAGE_NAME will be built without GMP support.])])
diff --git a/src/factor.c b/src/factor.c
index 5bfbfdc..843542b 100644
--- a/src/factor.c
+++ b/src/factor.c
@@ -526,6 +526,29 @@ factor_insert_large (struct factors *factors,
 }
 
 #if HAVE_GMP
+
+# if !HAVE_DECL_MPZ_INITS
+
+#  define mpz_inits(...) mpz_va_init (mpz_init, __VA_ARGS__)
+#  define mpz_clears(...) mpz_va_init (mpz_clear, __VA_ARGS__)
+
+static void
+mpz_va_init (void (*mpz_single_init)(mpz_t), mpz_ptr mpz, ...)
+{
+  va_list ap;
+
+  va_start (ap, mpz);
+
+  while (mpz != NULL)
+    {
+      mpz_single_init (mpz);
+      mpz = va_arg (ap, mpz_ptr);
+    }
+
+  va_end (ap);
+}
+# endif
+
 static void mp_factor (mpz_t, struct mp_factors *);
 
 static void
-- 
1.7.6.4