On Tue, 29 Nov 2022 at 23:11, Dean Rasheed <dean.a.rash...@gmail.com> wrote: > > On Wed, 23 Nov 2022 at 08:56, David Rowley <dgrowle...@gmail.com> wrote: > > > > On Wed, 23 Nov 2022 at 21:54, David Rowley <dgrowle...@gmail.com> wrote: > > > I wonder if you'd be better off with something like: > > > > > > while (*ptr && isxdigit((unsigned char) *ptr)) > > > { > > > if (unlikely(tmp & UINT64CONST(0xF000000000000000))) > > > goto out_of_range; > > > > > > tmp = (tmp << 4) | hexlookup[(unsigned char) *ptr++]; > > > } > > > > Here's a delta diff with it changed to work that way. > > > > This isn't correct, because those functions are meant to accumulate a > negative number in "tmp".
Looks like I didn't quite look at that code closely enough. To make that work we could just form the non-decimal versions in an unsigned integer of the given size and then check if that's become greater than -PG_INTXX_MIN after the loop. We'd then just need to convert it back to its negative form. i.e: uint64 tmp2 = 0; ptr += 2; while (*ptr && isxdigit((unsigned char) *ptr)) { if (unlikely(tmp2 & UINT64CONST(0xF000000000000000))) goto out_of_range; tmp2 = (tmp2 << 4) | hexlookup[(unsigned char) *ptr++]; } if (tmp2 > -PG_INT64_MIN) goto out_of_range; tmp = -((int64) tmp2); David