Update upstream OpenBSD gdtoa.
Also add a test for the bug that this fixes.
Bug: http://b/152588929
Test: treehugger
Change-Id: I58055b3ebaef457721bb4f5d8a8710025122b2e7
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index 878f71c..8206269 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -38,6 +38,8 @@
/* Ignore all __warn_references in OpenBSD. */
#define __warn_references(sym,msg)
+#define PROTO_NORMAL(x)
+
/* OpenBSD's <ctype.h> uses these names, which conflicted with stlport.
* Additionally, we changed the numeric/digit type from N to D for libcxx.
*/
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.h b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.h
index 9e1cea0..8d621b0 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.h
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.h
@@ -112,7 +112,18 @@
extern float strtof ANSI((CONST char *, char **));
extern double strtod ANSI((CONST char *, char **));
extern int __strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*));
+char *__hdtoa(double, const char *, int, int *, int *, char **);
+char *__hldtoa(long double, const char *, int, int *, int *, char **);
+char *__ldtoa(long double *, int, int, int *, int *, char **);
+PROTO_NORMAL(__dtoa);
+PROTO_NORMAL(__gdtoa);
+PROTO_NORMAL(__freedtoa);
+PROTO_NORMAL(__hdtoa);
+PROTO_NORMAL(__hldtoa);
+PROTO_NORMAL(__ldtoa);
+
+__BEGIN_HIDDEN_DECLS
extern char* __g_ddfmt ANSI((char*, double*, int, size_t));
extern char* __g_dfmt ANSI((char*, double*, int, size_t));
extern char* __g_ffmt ANSI((char*, float*, int, size_t));
@@ -148,6 +159,7 @@
#define __strtopx(s,se,x) strtorx(s,se,1,x)
#define __strtopxL(s,se,x) strtorxL(s,se,1,x)
#endif
+__END_HIDDEN_DECLS
#ifdef __cplusplus
}
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
index 0f3de12..823f2a9 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
@@ -463,7 +463,6 @@
#define FREE_DTOA_LOCK(n) /*nothing*/
#else
#include "thread_private.h"
-extern void *__dtoa_locks[];
#define ACQUIRE_DTOA_LOCK(n) _MUTEX_LOCK(&__dtoa_locks[n])
#define FREE_DTOA_LOCK(n) _MUTEX_UNLOCK(&__dtoa_locks[n])
#endif
@@ -567,6 +566,7 @@
#define trailz __trailz_D2A
#define ulp __ulp_D2A
+__BEGIN_HIDDEN_DECLS
extern char *dtoa_result;
extern CONST double bigtens[], tens[], tinytens[];
extern unsigned char hexdig[];
@@ -586,8 +586,6 @@
extern Bigint *d2b ANSI((double, int*, int*));
extern void decrement ANSI((Bigint*));
extern Bigint *diff ANSI((Bigint*, Bigint*));
- extern char *dtoa ANSI((double d, int mode, int ndigits,
- int *decpt, int *sign, char **rve));
extern char *g__fmt ANSI((char*, char*, char*, int, ULong, size_t));
extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int));
extern void __hexdig_init_D2A(Void);
@@ -610,10 +608,10 @@
extern Bigint *set_ones ANSI((Bigint*, int));
extern char *strcp ANSI((char*, const char*));
extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*));
- extern double strtod ANSI((const char *s00, char **se));
extern Bigint *sum ANSI((Bigint*, Bigint*));
extern int trailz ANSI((Bigint*));
extern double ulp ANSI((U*));
+__END_HIDDEN_DECLS
#ifdef __cplusplus
}
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c b/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c
index f521f15..d48c9ed 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c
@@ -57,11 +57,8 @@
static unsigned char *decimalpoint_cache;
if (!(s0 = decimalpoint_cache)) {
s0 = (unsigned char*)localeconv()->decimal_point;
- if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
- strlcpy(decimalpoint_cache, s0, strlen(s0) + 1);
- s0 = decimalpoint_cache;
- }
- }
+ decimalpoint_cache = strdup(s0);
+ }
decimalpoint = s0;
#endif
#endif
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c b/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c
index 45caef4..4a7f798 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hdtoa.c,v 1.3 2015/09/14 12:49:33 guenther Exp $ */
+/* $OpenBSD: hdtoa.c,v 1.5 2020/05/31 12:27:19 mortimer Exp $ */
/*-
* Copyright (c) 2004, 2005 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
@@ -112,7 +112,7 @@
*
* Note that the C99 standard does not specify what the leading digit
* should be for non-zero numbers. For instance, 0x1.3p3 is the same
- * as 0x2.6p2 is the same as 0x4.cp3. This implementation chooses the
+ * as 0x2.6p2 is the same as 0x4.cp1. This implementation chooses the
* first digit so that subsequent digits are aligned on nibble
* boundaries (before rounding).
*
@@ -225,6 +225,7 @@
struct ieee_ext *p = (struct ieee_ext *)&e;
char *s, *s0;
int bufsize;
+ int fbits = 0;
*sign = p->ext_sign;
@@ -273,23 +274,24 @@
*/
for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--)
*s = 0;
- for (; s > s0 + sigfigs - (EXT_FRACLBITS / 4) - 1 && s > s0; s--) {
+
+ for (fbits = EXT_FRACLBITS / 4; fbits > 0 && s > s0; s--, fbits--) {
*s = p->ext_fracl & 0xf;
p->ext_fracl >>= 4;
}
-#ifdef EXT_FRACHMBITS
- for (; s > s0; s--) {
- *s = p->ext_frachm & 0xf;
- p->ext_frachm >>= 4;
- }
-#endif
#ifdef EXT_FRACLMBITS
- for (; s > s0; s--) {
+ for (fbits = EXT_FRACLMBITS / 4; fbits > 0 && s > s0; s--, fbits--) {
*s = p->ext_fraclm & 0xf;
p->ext_fraclm >>= 4;
}
#endif
- for (; s > s0; s--) {
+#ifdef EXT_FRACHMBITS
+ for (fbits = EXT_FRACHMBITS / 4; fbits > 0 && s > s0; s--, fbits--) {
+ *s = p->ext_frachm & 0xf;
+ p->ext_frachm >>= 4;
+ }
+#endif
+ for (fbits = EXT_FRACHBITS / 4; fbits > 0 && s > s0; s--, fbits--) {
*s = p->ext_frach & 0xf;
p->ext_frach >>= 4;
}
@@ -300,7 +302,7 @@
* (partial) nibble, which is dealt with by the next
* statement. We also tack on the implicit normalization bit.
*/
- *s = p->ext_frach | (1U << ((LDBL_MANT_DIG - 1) % 4));
+ *s = (p->ext_frach | (1U << ((LDBL_MANT_DIG - 1) % 4))) & 0xf;
/* If ndigits < 0, we are expected to auto-size the precision. */
if (ndigits < 0) {
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/misc.c b/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
index b149f07..79a3104 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
@@ -40,6 +40,10 @@
static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
#endif
+#ifdef MULTIPLE_THREADS
+extern void *__dtoa_locks[];
+#endif
+
Bigint *
Balloc
#ifdef KR_headers
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c b/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c
index ac2283c..0fb37fd 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c
@@ -114,10 +114,7 @@
static int dplen;
if (!(s0 = decimalpoint_cache)) {
s0 = localeconv()->decimal_point;
- if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
- strlcpy(decimalpoint_cache, s0, strlen(s0) + 1);
- s0 = decimalpoint_cache;
- }
+ decimalpoint_cache = strdup(s0);
dplen = strlen(s0);
}
decimalpoint = (char*)s0;
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/strtodg.c b/libc/upstream-openbsd/lib/libc/gdtoa/strtodg.c
index 753f6bf..defb474 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/strtodg.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/strtodg.c
@@ -363,10 +363,7 @@
static int dplen;
if (!(s0 = decimalpoint_cache)) {
s0 = localeconv()->decimal_point;
- if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
- strlcpy(decimalpoint_cache, s0, strlen(s0) + 1);
- s0 = decimalpoint_cache;
- }
+ decimalpoint_cache = strdup(s0);
dplen = strlen(s0);
}
decimalpoint = (char*)s0;