ruby-changes:46582
From: nobu <ko1@a...>
Date: Sat, 13 May 2017 10:05:36 +0900 (JST)
Subject: [ruby-changes:46582] nobu:r58698 (trunk): math.c: check argument to lgamma_r
nobu 2017-05-13 10:05:30 +0900 (Sat, 13 May 2017) New Revision: 58698 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=58698 Log: math.c: check argument to lgamma_r * math.c (math_lgamma): check the argument before calling math function `lgamma_r` for edge cases. Modified files: trunk/configure.in trunk/math.c Index: math.c =================================================================== --- math.c (revision 58697) +++ math.c (revision 58698) @@ -778,22 +778,6 @@ math_erfc(VALUE unused_obj, VALUE x) https://github.com/ruby/ruby/blob/trunk/math.c#L778 return DBL2NUM(erfc(Get_Double(x))); } -#if defined LGAMMA_R_PM0_FIX -static inline double -ruby_lgamma_r(const double d, int *sign) -{ - const double g = lgamma_r(d, sign); - if (isinf(g)) { - if (d == 0.0) { - *sign = signbit(d) ? -1 : +1; - return INFINITY; - } - } - return g; -} -#define lgamma_r(d, sign) ruby_lgamma_r(d, sign) -#endif - /* * call-seq: * Math.gamma(x) -> Float @@ -911,6 +895,10 @@ math_lgamma(VALUE unused_obj, VALUE x) https://github.com/ruby/ruby/blob/trunk/math.c#L895 if (signbit(d)) domain_error("lgamma"); return rb_assoc_new(DBL2NUM(INFINITY), INT2FIX(1)); } + if (d == 0.0) { + VALUE vsign = signbit(d) ? INT2FIX(-1) : INT2FIX(+1); + return rb_assoc_new(DBL2NUM(INFINITY), vsign); + } v = DBL2NUM(lgamma_r(d, &sign)); return rb_assoc_new(v, INT2FIX(sign)); } Index: configure.in =================================================================== --- configure.in (revision 58697) +++ configure.in (revision 58698) @@ -2639,47 +2639,6 @@ main(int argc, char **argv) https://github.com/ruby/ruby/blob/trunk/configure.in#L2639 ]) AS_IF([test "x$rb_cv_atan2_inf_c99" = xyes], [AC_DEFINE(ATAN2_INF_C99)]) -AS_IF([test "x$ac_cv_func_lgamma_r" = xyes], [ - AC_CACHE_CHECK(whether lgamma_r handles +0.0 and -0.0, rb_cv_lgamma_r_pm0, [ - AC_TRY_RUN([ -@%:@include <math.h> -@%:@ifdef HAVE_UNISTD_H -@%:@include <unistd.h> -@%:@endif -@%:@ifndef EXIT_SUCCESS -@%:@define EXIT_SUCCESS 0 -@%:@endif -@%:@ifndef EXIT_FAILURE -@%:@define EXIT_FAILURE 1 -@%:@endif - -int -main(int argc, char **argv) -{ - int sign = 0; - double x = lgamma_r(-0.0, &sign); - - /* should be [+inf, -1] */ - if (x <= 0) return EXIT_FAILURE; - if (!isinf(x)) return EXIT_FAILURE; - if (sign != -1) return EXIT_FAILURE; - - /* should be [+inf, 1] */ - x = lgamma_r(+0.0, &sign); - if (x <= 0) return EXIT_FAILURE; - if (!isinf(x)) return EXIT_FAILURE; - if (sign != 1) return EXIT_FAILURE; - return EXIT_SUCCESS; -} -], - [rb_cv_lgamma_r_pm0=yes], - [rb_cv_lgamma_r_pm0=no], - [rb_cv_lgamma_r_pm0=yes] - ) - ]) - AS_IF([test "x$rb_cv_lgamma_r_pm0" = xno], [AC_DEFINE(LGAMMA_R_PM0_FIX)]) -]) - # Some platform need -lrt for clock_gettime, but the other don't. if test x"$ac_cv_func_clock_gettime" != xyes; then # glibc 2.17 moves clock_* functions from librt to the main C library. -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/